diff --git a/DEPS b/DEPS
index 8b6d1a8..bba3f2a 100644
--- a/DEPS
+++ b/DEPS
@@ -285,7 +285,7 @@
   'sysroots_json_path': 'build/linux/sysroot_scripts/sysroots.json',
 
   # siso CIPD package version.
-  'siso_version': 'git_revision:6af7e19f74a94ee61f1ddabc0d23b8e3c0d02e98',
+  'siso_version': 'git_revision:9aef05a1a1bddf2cf8e60bc7d9312c7afbfbe9a2',
 
   # download libaom test data
   'download_libaom_testdata': False,
@@ -305,15 +305,15 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'src_internal_revision': 'd03e9b687fa3fb8a7deb59711777a7947b21252c',
+  'src_internal_revision': '95496cacbb6d27a923918e1b7c1ef143b79c45b5',
   # 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': '2b218381e226d986a9b43789d8822b1ce4d80516',
+  'skia_revision': 'e3cf4d9ffc3841d7b032e2549204bcceddd0946a',
   # 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': '9f07854eb0b779fa46b8b64bbc1da4e4a7572878',
+  'v8_revision': '9565fefb3b06c758a9ad4f833f4696f6027fc0ee',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
@@ -325,7 +325,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '0a34b6b287747f2911474375ab7d3d7367d9e049',
+  'pdfium_revision': '6a34da391b15f5373247fda48c10a12bc4143c94',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
@@ -360,7 +360,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
-  'freetype_revision': 'e9202737747ac008819d24a39c54584200c7a254',
+  'freetype_revision': '6338f2a6814b3f50a0bb3a4c563ef30e4561041a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
@@ -380,11 +380,11 @@
   # 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': 'c6db8519c02ae6a5afac0358c266dc3e5f2fd803',
+  'catapult_revision': '124950ee2c619428b16fabb3a5389fcbcfd7d665',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling chromium_variations
   # and whatever else without interference from each other.
-  'chromium_variations_revision': '37afeb4fa9594d2497b5b8e13a94509c54201680',
+  'chromium_variations_revision': '080ed7fb83d2605473c71f2661185fe3364d8a34',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling CrossBench
   # and whatever else without interference from each other.
@@ -400,7 +400,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': '1088b0366ce6feff0dab1f8ef102a6d2ee801ed3',
+  'devtools_frontend_revision': 'fb3ba5ad261f335023e2c2160b8a9b59f5770075',
   # 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.
@@ -414,33 +414,17 @@
   # and whatever else without interference from each other.
   'android_sdk_emulator_version': '9lGp8nTUCRRWGMnI_96HcKfzjnxEJKUcfvfwmA3wXNkC',
   # Three lines of non-changing comments so that
-  # the commit queue can handle CLs rolling android_sdk_extras_version
-  # and whatever else without interference from each other.
-  'android_sdk_extras_version': 'ppQ4TnqDvBHQ3lXx5KPq97egzF5X2FFyOrVHkGmiTMQC',
-  # Three lines of non-changing comments so that
-  # the commit queue can handle CLs rolling android_sdk_patcher_version
-  # and whatever else without interference from each other.
-  'android_sdk_patcher_version': 'I6FNMhrXlpB-E1lOhMlvld7xt9lBVNOO83KIluXDyA0C',
-  # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling android_sdk_platform-tools_version
   # and whatever else without interference from each other.
   'android_sdk_platform-tools_version': 'HWVsGs2HCKgSVv41FsOcsfJbNcB0UFiNrF6Tc4yRArYC',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling android_sdk_platforms_version
   # and whatever else without interference from each other.
-  'android_sdk_platforms_preview_version': 'YWMYkzyxGBgVsty0GhXL1oxbY0pGXQIgFc0Rh7ZMRPYC',
-  # Three lines of non-changing comments so that
-  # the commit queue can handle CLs rolling android_sdk_platforms_version
-  # and whatever else without interference from each other.
   'android_sdk_platforms_version': 'u-bhWbTME6u-DjypTgr3ZikCyeAeU6txkR9ET6Uudc8C',
   # Three lines of non-changing comments so that
-  # the commit queue can handle CLs rolling android_sdk_sources_version
-  # and whatever else without interference from each other.
-  'android_sdk_sources_version': '_a_BcnANjPYw5mSKlNHa7GFY8yc1kdqj2rmQgac7yUcC',
-  # 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': 'e2cd8aade99ffd2d2b97fe87fd43b08f22002692',
+  'dawn_revision': '6f2cbf61890b1a644269326bc50dd82bcaf58f7e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -484,7 +468,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'cros_components_revision': 'd409ac304472ac7b2ea569d9e3ac47d238de1182',
+  'cros_components_revision': 'c3435a5e6829b9a4746456e5a1beb2ef23926be4',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -516,7 +500,7 @@
 
   # If you change this, also update the libc++ revision in
   # //buildtools/deps_revisions.gni.
-  'libcxx_revision':       'd781e6e1b823d1391179f52516e0fc93e61567b2',
+  'libcxx_revision':       '2364ae8b073e44c9ac2725e176f2ce57967f1012',
 
   # GN CIPD package version.
   'gn_version': 'git_revision:e4702d7409069c4f12d45ea7b7f0890717ca3f4b',
@@ -840,7 +824,7 @@
 
   'src/clank': {
     'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' +
-    'c000cb71605baf6bfb5e5bcc6765491ccedc7369',
+    '4cee13aad60c25a716fcf4015117580851516cb9',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
@@ -1002,7 +986,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': '7gw0P2lS-ut2s5t50FOrENILfpO4Z8dgj0tIwzxV448C',
+          'version': 'aVJu6XpoGjuM7ZLLWTSig6vVpDKwmZicETA8bPF3mloC',
       },
     ],
     'condition': 'checkout_android',
@@ -1091,10 +1075,6 @@
               'version': Var('android_sdk_emulator_version'),
           },
           {
-              'package': 'chromium/third_party/android_sdk/public/patcher',
-              'version': Var('android_sdk_patcher_version'),
-          },
-          {
               'package': 'chromium/third_party/android_sdk/public/platform-tools',
               'version': Var('android_sdk_platform-tools_version'),
           },
@@ -1103,14 +1083,6 @@
               'version': Var('android_sdk_platforms_version'),
           },
           {
-              'package': 'chromium/third_party/android_sdk/public/platforms/android-tiramisuprivacysandbox',
-              'version': Var('android_sdk_platforms_preview_version'),
-          },
-          {
-              'package': 'chromium/third_party/android_sdk/public/sources/android-31',
-              'version': Var('android_sdk_sources_version'),
-          },
-          {
               'package': 'chromium/third_party/android_sdk/public/cmdline-tools',
               'version': 'Sy00LuyBIUJdRGYKwg0zjWH8eAIUvgnnNiPkI8etaZYC',
           },
@@ -1246,13 +1218,13 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '0c5e8652fe1fefee1c291cbf05ca3a41b9f66890',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'ccc34d2b44d8520f9b4c2697001f36444c78cd66',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
 
   'src/third_party/devtools-frontend-internal': {
-      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '2c4d976019118bab0f3e12634570728fcb658494',
+      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '54c8de91358fc2d5d39b20ba4a159bbe4dae2c22',
     'condition': 'checkout_src_internal',
   },
 
@@ -1717,7 +1689,7 @@
     Var('pdfium_git') + '/pdfium.git' + '@' +  Var('pdfium_revision'),
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '33063c9403c381f5411e1cddf8688a912529b4d9',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '6f755e28a296d022cb03c3843ea6cc2c45176778',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1899,10 +1871,10 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'f4bf599a8b575df685c31d9c4729a70a04e377ed',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '1c407e0944032ac9877bf4e5e000acff7a591b73',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '149e02ab793f6a323a5ea4a3d2f52547aefc1434',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + 'be04c98d6488fc86594424e39c16d849f8628e27',
+    Var('webrtc_git') + '/src.git' + '@' + 'bd523afd3ab69c882e5e50a7fcc4b28bbd9e0d43',
 
   # Wuffs' canonical repository is at github.com/google/wuffs, but we use
   # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file.
@@ -2014,7 +1986,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/eche_app/app',
-        'version': '2NI5WVCd4BxTVFnuJ_vn2hPcWgAhq2S8-SmA7Fcx6kMC',
+        'version': 'i58yHfqcc04Op-UZnR16jEzJWjLKKic5rbQeWf3unA4C',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -2036,7 +2008,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': 'mSWQ0RLZiW3kRJkQ0e6wnyV3wsreJO6LorA4gNT04mEC',
+        'version': 'it51OzLS9K0nv1Oe7mPXLOaOWNbYZAdw1v9wiv-QwGQC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -2069,7 +2041,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/projector_app/app',
-        'version': 'RLJSHUDpQ9VqoDHiNPXGBzlh_TffuF8H8gLoS62pEIAC',
+        'version': 'z4I6TtdTUSAPZ-F6GFA-TjauqCZwu_CrTOX6U1ShJPkC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -4059,7 +4031,7 @@
 
   'src/ios_internal':  {
       'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' +
-        '1be9791237c4cd9def25d4b0276868f05aae5ba6',
+        'f9a83e85a8584ef7fc1bc0ecdfb5c0e5e4468242',
       'condition': 'checkout_ios and checkout_src_internal',
   },
 
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/SharedWebViewContentsClientAdapter.java b/android_webview/glue/java/src/com/android/webview/chromium/SharedWebViewContentsClientAdapter.java
index f20fb5e..2b7fd8b4 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/SharedWebViewContentsClientAdapter.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/SharedWebViewContentsClientAdapter.java
@@ -171,8 +171,9 @@
                         mWebViewClient, mWebView, request, threatType, callback);
 
             } else {
-                callback.onResult(new AwSafeBrowsingResponse(SafeBrowsingAction.SHOW_INTERSTITIAL,
-                        /* reporting */ true));
+                callback.onResult(
+                        new AwSafeBrowsingResponse(
+                                SafeBrowsingAction.SHOW_INTERSTITIAL, /* reporting= */ true));
             }
         }
     }
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java
index eb504c2..8b5f807 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumAwInit.java
@@ -110,7 +110,7 @@
         mFactory = factory;
         // Do not make calls into 'factory' in this ctor - this ctor is called from the
         // WebViewChromiumFactoryProvider ctor, so 'factory' is not properly initialized yet.
-        TraceEvent.maybeEnableEarlyTracing(/*readCommandLine=*/false);
+        TraceEvent.maybeEnableEarlyTracing(/* readCommandLine= */ false);
     }
 
     public AwTracingController getAwTracingController() {
@@ -208,7 +208,7 @@
             }
 
             AwBrowserProcess.start();
-            AwBrowserProcess.handleMinidumpsAndSetMetricsConsent(true /* updateMetricsConsent */);
+            AwBrowserProcess.handleMinidumpsAndSetMetricsConsent(/* updateMetricsConsent= */ true);
 
             // This has to be done after variations are initialized, so components could be
             // registered or not depending on the variations flags.
diff --git a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
index c5f4976..486d1b48 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
@@ -153,9 +153,14 @@
         final boolean isExternalService = true;
         final boolean bindToCaller = true;
         final boolean ignoreVisibilityForImportance = true;
-        ChildProcessCreationParams.set(getWebViewPackageName(), null /* privilegedServicesName */,
-                getWebViewPackageName(), null /* sandboxedServicesName */, isExternalService,
-                LibraryProcessType.PROCESS_WEBVIEW_CHILD, bindToCaller,
+        ChildProcessCreationParams.set(
+                getWebViewPackageName(),
+                /* privilegedServicesName= */ null,
+                getWebViewPackageName(),
+                /* sandboxedServicesName= */ null,
+                isExternalService,
+                LibraryProcessType.PROCESS_WEBVIEW_CHILD,
+                bindToCaller,
                 ignoreVisibilityForImportance);
     }
 
@@ -172,36 +177,42 @@
             // We must post to the UI thread to cover the case that the user
             // has invoked Chromium startup by using the (thread-safe)
             // CookieManager rather than creating a WebView.
-            ThreadUtils.runOnUiThreadBlocking(() -> {
-                boolean multiProcess =
-                        CommandLine.getInstance().hasSwitch(AwSwitches.WEBVIEW_SANDBOXED_RENDERER);
-                if (multiProcess) {
-                    ChildProcessLauncherHelper.warmUp(appContext, true);
-                }
-                // The policies are used by browser startup, so we need to register the policy
-                // providers before starting the browser process. This only registers java objects
-                // and doesn't need the native library.
-                CombinedPolicyProvider.get().registerProvider(new AwPolicyProvider(appContext));
+            ThreadUtils.runOnUiThreadBlocking(
+                    () -> {
+                        boolean multiProcess =
+                                CommandLine.getInstance()
+                                        .hasSwitch(AwSwitches.WEBVIEW_SANDBOXED_RENDERER);
+                        if (multiProcess) {
+                            ChildProcessLauncherHelper.warmUp(appContext, true);
+                        }
+                        // The policies are used by browser startup, so we need to register the
+                        // policy providers before starting the browser process. This only registers
+                        // java objects and doesn't need the native library.
+                        CombinedPolicyProvider.get()
+                                .registerProvider(new AwPolicyProvider(appContext));
 
-                // Check android settings but only when safebrowsing is enabled.
-                try (ScopedSysTraceEvent e2 =
+                        // Check android settings but only when safebrowsing is enabled.
+                        try (ScopedSysTraceEvent e2 =
                                 ScopedSysTraceEvent.scoped("AwBrowserProcess.maybeEnable")) {
-                    AwSafeBrowsingConfigHelper.maybeEnableSafeBrowsingFromManifest();
-                }
+                            AwSafeBrowsingConfigHelper.maybeEnableSafeBrowsingFromManifest();
+                        }
 
-                try (ScopedSysTraceEvent e2 = ScopedSysTraceEvent.scoped(
-                             "AwBrowserProcess.startBrowserProcessesSync")) {
-                    BrowserStartupController.getInstance().startBrowserProcessesSync(
-                            LibraryProcessType.PROCESS_WEBVIEW, !multiProcess,
-                            /*startGpuProcess=*/false);
-                }
+                        try (ScopedSysTraceEvent e2 =
+                                ScopedSysTraceEvent.scoped(
+                                        "AwBrowserProcess.startBrowserProcessesSync")) {
+                            BrowserStartupController.getInstance()
+                                    .startBrowserProcessesSync(
+                                            LibraryProcessType.PROCESS_WEBVIEW,
+                                            !multiProcess,
+                                            /* startGpuProcess= */ false);
+                        }
 
-                PowerMonitor.create();
-                PlatformServiceBridge.getInstance().setSafeBrowsingHandler();
-                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
-                    AwContentsLifecycleNotifier.initialize();
-                }
-            });
+                        PowerMonitor.create();
+                        PlatformServiceBridge.getInstance().setSafeBrowsingHandler();
+                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+                            AwContentsLifecycleNotifier.initialize();
+                        }
+                    });
         }
 
         PostTask.postTask(
@@ -258,7 +269,7 @@
      */
     @CalledByNative
     private static void triggerMinidumpUploading() {
-        handleMinidumpsAndSetMetricsConsent(false /* updateMetricsConsent */);
+        handleMinidumpsAndSetMetricsConsent(/* updateMetricsConsent= */ false);
     }
 
     /**
@@ -273,7 +284,7 @@
             final boolean enableMinidumpUploadingForTesting = CommandLine.getInstance().hasSwitch(
                     BaseSwitches.ENABLE_CRASH_REPORTER_FOR_TESTING);
             if (enableMinidumpUploadingForTesting) {
-                handleMinidumps(true /* enabled */);
+                handleMinidumps(/* enabled */ true);
             }
 
             PlatformServiceBridge.getInstance().queryMetricsSetting(enabled -> {
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index cca380c..c49f18c 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -870,14 +870,14 @@
         public void onScrollStarted(int scrollOffsetY, int scrollExtentY, boolean isDirectionUp) {
             mZoomControls.invokeZoomPicker();
             if (mAwFrameMetricsListener != null) {
-                mAwFrameMetricsListener.onWebContentsScrollStateUpdate(/*isScrolling=*/true);
+                mAwFrameMetricsListener.onWebContentsScrollStateUpdate(/* isScrolling= */ true);
             }
         }
 
         @Override
         public void onScrollEnded(int scrollOffsetY, int scrollExtentY) {
             if (mAwFrameMetricsListener != null) {
-                mAwFrameMetricsListener.onWebContentsScrollStateUpdate(/*isScrolling=*/false);
+                mAwFrameMetricsListener.onWebContentsScrollStateUpdate(/* isScrolling= */ false);
             }
         }
 
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsBackgroundThreadClient.java b/android_webview/java/src/org/chromium/android_webview/AwContentsBackgroundThreadClient.java
index 8a017f8..0804b62 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContentsBackgroundThreadClient.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContentsBackgroundThreadClient.java
@@ -34,10 +34,15 @@
             String[] requestHeaderValues) {
         try {
             return new AwWebResourceInterceptResponse(
-                    shouldInterceptRequest(new AwContentsClient.AwWebResourceRequest(url,
-                            isMainFrame, hasUserGesture, method, requestHeaderNames,
-                            requestHeaderValues)),
-                    /*raisedException=*/false);
+                    shouldInterceptRequest(
+                            new AwContentsClient.AwWebResourceRequest(
+                                    url,
+                                    isMainFrame,
+                                    hasUserGesture,
+                                    method,
+                                    requestHeaderNames,
+                                    requestHeaderValues)),
+                    /* raisedException= */ false);
         } catch (Throwable e) {
             Log.e(TAG,
                     "Client raised exception in shouldInterceptRequest. Re-throwing on UI thread.");
@@ -47,7 +52,7 @@
                 throw e;
             });
 
-            return new AwWebResourceInterceptResponse(null, /*raisedException=*/true);
+            return new AwWebResourceInterceptResponse(null, /* raisedException= */ true);
         }
     }
 }
diff --git a/android_webview/java/src/org/chromium/android_webview/common/DeveloperModeUtils.java b/android_webview/java/src/org/chromium/android_webview/common/DeveloperModeUtils.java
index c99f657..c941141 100644
--- a/android_webview/java/src/org/chromium/android_webview/common/DeveloperModeUtils.java
+++ b/android_webview/java/src/org/chromium/android_webview/common/DeveloperModeUtils.java
@@ -91,8 +91,15 @@
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
             startDeveloperUiService(webViewPackageName);
         }
-        try (Cursor cursor = appContext.getContentResolver().query(uri, /* projection */ null,
-                     /* selection */ null, /* selectionArgs */ null, /* sortOrder */ null)) {
+        try (Cursor cursor =
+                appContext
+                        .getContentResolver()
+                        .query(
+                                uri,
+                                /* projection= */ null,
+                                /* selection= */ null,
+                                /* selectionArgs= */ null,
+                                /* sortOrder= */ null)) {
             assert cursor != null : "ContentProvider doesn't support querying '" + uri + "'";
             int flagNameColumnIndex = cursor.getColumnIndexOrThrow(FLAG_OVERRIDE_NAME_COLUMN);
             int flagStateColumnIndex = cursor.getColumnIndexOrThrow(FLAG_OVERRIDE_STATE_COLUMN);
diff --git a/android_webview/java/src/org/chromium/android_webview/common/Flag.java b/android_webview/java/src/org/chromium/android_webview/common/Flag.java
index 2cdc117..93fdfd89 100644
--- a/android_webview/java/src/org/chromium/android_webview/common/Flag.java
+++ b/android_webview/java/src/org/chromium/android_webview/common/Flag.java
@@ -22,21 +22,21 @@
      * overload will not have a user-visible flag description.
      */
     public static Flag baseFeature(@NonNull String name) {
-        return new Flag(name, /*description=*/"", /*enabledStateValue=*/null, true);
+        return new Flag(name, /* description= */ "", /* enabledStateValue= */ null, true);
     }
 
     /**
      * Creates a Flag which represents a {@code base::Feature}.
      */
     public static Flag baseFeature(@NonNull String name, @NonNull String description) {
-        return new Flag(name, description, /*enabledStateValue=*/null, true);
+        return new Flag(name, description, /* enabledStateValue= */ null, true);
     }
 
     /**
      * Creates a Flag which represents a commandline switch.
      */
     public static Flag commandLine(@NonNull String name, @NonNull String description) {
-        return new Flag(name, description, /*enabledStateValue=*/null, false);
+        return new Flag(name, description, /* enabledStateValue= */ null, false);
     }
 
     /**
diff --git a/android_webview/java/src/org/chromium/android_webview/metrics/TrackExitReasonsOfInterest.java b/android_webview/java/src/org/chromium/android_webview/metrics/TrackExitReasonsOfInterest.java
index 16c9ae4a..e01a1f0 100644
--- a/android_webview/java/src/org/chromium/android_webview/metrics/TrackExitReasonsOfInterest.java
+++ b/android_webview/java/src/org/chromium/android_webview/metrics/TrackExitReasonsOfInterest.java
@@ -173,14 +173,14 @@
      */
     @VisibleForTesting
     public static boolean writeLastExitInfo(final ExitReasonData newData) {
-        return writeLastExitInfo(newData, /*callbackResult=*/null);
+        return writeLastExitInfo(newData, /* callbackResult= */ null);
     }
 
     @VisibleForTesting
     public static boolean writeLastExitInfo(
             final ExitReasonData newData, final Callback<Boolean> callbackResult) {
         try (FileOutputStream writer =
-                        new FileOutputStream(getLastExitInfoFile(), /*append=*/false)) {
+                new FileOutputStream(getLastExitInfoFile(), /* append= */ false)) {
             JSONObject jsonObj = new JSONObject();
             jsonObj.put(LAST_EXIT_INFO_PID, newData.mExitInfoPid);
             jsonObj.put(TIMESTAMP_AT_LAST_RECORDING_IN_MILLIS,
@@ -213,7 +213,7 @@
      * Commits the latest app state for exit reason tracking to disk.
      */
     public static void writeLastWebViewState() {
-        writeLastWebViewState(/*callbackResult=*/null);
+        writeLastWebViewState(/* callbackResult= */ null);
     }
 
     /**
diff --git a/android_webview/java/src/org/chromium/android_webview/variations/VariationsSeedLoader.java b/android_webview/java/src/org/chromium/android_webview/variations/VariationsSeedLoader.java
index 47fe78c..6679fbb 100644
--- a/android_webview/java/src/org/chromium/android_webview/variations/VariationsSeedLoader.java
+++ b/android_webview/java/src/org/chromium/android_webview/variations/VariationsSeedLoader.java
@@ -114,9 +114,12 @@
     private static void recordAppSeedFreshness(long freshnessMinutes) {
         // Bucket parameters should match Variations.SeedFreshness.
         // See variations::RecordSeedFreshness.
-        RecordHistogram.recordCustomCountHistogram(APP_SEED_FRESHNESS_HISTOGRAM_NAME,
-                (int) freshnessMinutes, /*min=*/1, /*max=*/(int) TimeUnit.DAYS.toMinutes(30),
-                /*numBuckets=*/50);
+        RecordHistogram.recordCustomCountHistogram(
+                APP_SEED_FRESHNESS_HISTOGRAM_NAME,
+                (int) freshnessMinutes,
+                /* min= */ 1,
+                /* max= */ (int) TimeUnit.DAYS.toMinutes(30),
+                /* numBuckets= */ 50);
     }
 
     private static void recordMinuteHistogram(String name, long value, long maxValue) {
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwActivityTestRule.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwActivityTestRule.java
index cfacfb41..2b1773a 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwActivityTestRule.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwActivityTestRule.java
@@ -523,7 +523,7 @@
     public String executeJavaScriptAndWaitForResult(final AwContents awContents,
             TestAwContentsClient viewClient, final String code) throws Exception {
         return executeJavaScriptAndWaitForResult(
-                awContents, viewClient, code, /*shouldCheckSettings=*/true);
+                awContents, viewClient, code, /* shouldCheckSettings= */ true);
     }
 
     /**
@@ -793,10 +793,13 @@
         }
 
         public AwSettings createAwSettings(Context context, boolean supportsLegacyQuirks) {
-            return new AwSettings(context, false /* isAccessFromFileURLsGrantedByDefault */,
-                    supportsLegacyQuirks, false /* allowEmptyDocumentPersistence */,
-                    true /* allowGeolocationOnInsecureOrigins */,
-                    false /* doNotUpdateSelectionOnMutatingSelectionRange */);
+            return new AwSettings(
+                    context,
+                    /* isAccessFromFileURLsGrantedByDefault= */ false,
+                    supportsLegacyQuirks,
+                    /* allowEmptyDocumentPersistence= */ false,
+                    /* allowGeolocationOnInsecureOrigins= */ true,
+                    /* doNotUpdateSelectionOnMutatingSelectionRange= */ false);
         }
 
         public AwContents createAwContents(AwBrowserContext browserContext, ViewGroup containerView,
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java
index 1da0626..4ef6787 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java
@@ -1309,7 +1309,7 @@
     @Feature({"AndroidWebView"})
     public void testWindowOpenAboutBlankInPopup() throws Throwable {
         TestAwContentsClient.ShouldOverrideUrlLoadingHelper popupShouldOverrideUrlLoadingHelper =
-                createPopUp("about:blank", true /* wait for title */);
+                createPopUp("about:blank", /* waitForTitle= */ true);
         // Popup is just created, so testing against 0 is true.
         Assert.assertEquals(0, popupShouldOverrideUrlLoadingHelper.getCallCount());
     }
@@ -1397,7 +1397,7 @@
     private void verifyShouldOverrideUrlLoadingInPopup(
             String popupPath, String expectedPathInShouldOVerrideUrlLoading) throws Throwable {
         TestAwContentsClient.ShouldOverrideUrlLoadingHelper popupShouldOverrideUrlLoadingHelper =
-                createPopUp(popupPath, false /* wait for onpagefinished */);
+                createPopUp(popupPath, /* waitForTitle= */ false);
         Assert.assertEquals(
                 expectedPathInShouldOVerrideUrlLoading,
                 popupShouldOverrideUrlLoadingHelper.getShouldOverrideUrlLoadingUrl());
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
index f21bd83..4b54df29 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
@@ -2109,9 +2109,9 @@
         // ends with platform string and user-agent string.
         Assert.assertTrue(
                 actualTitleContent.endsWith(
-                        /*sec-ch-ua-platform=*/ "\"Android\" "
+                        /* sec-ch-ua-platform= */ "\"Android\" "
                                 +
-                                /*user-agent=*/ customUserAgentString));
+                                /* user-agent= */ customUserAgentString));
         // Sec-ch-ua value has brand AndroidWebview.
         Assert.assertTrue(actualTitleContent.indexOf("\"Android WebView\";v=\"") != -1);
     }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/MetricsTestPlatformServiceBridge.java b/android_webview/javatests/src/org/chromium/android_webview/test/MetricsTestPlatformServiceBridge.java
index 4f16324..e2363a0 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/MetricsTestPlatformServiceBridge.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/MetricsTestPlatformServiceBridge.java
@@ -36,7 +36,7 @@
     @Override
     public void queryMetricsSetting(Callback<Boolean> callback) {
         ThreadUtils.assertOnUiThread();
-        callback.onResult(true /* enabled */);
+        callback.onResult(/* enabled= */ true);
     }
 
     @Override
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/PolicyUrlFilteringTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/PolicyUrlFilteringTest.java
index 85cd30b8..8ef07dd 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/PolicyUrlFilteringTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/PolicyUrlFilteringTest.java
@@ -101,11 +101,13 @@
         TestThreadUtils.runOnUiThreadBlocking(
                 () -> CombinedPolicyProvider.get().registerProvider(testProvider));
 
-        navigateAndCheckOutcome(mFooTestUrl, 0 /* error count before */, 0 /* error count after*/);
+        navigateAndCheckOutcome(
+                mFooTestUrl, /* startingErrorCount= */ 0, /* expectedErrorCount= */ 0);
 
         setFilteringPolicy(testProvider, new String[] {"localhost"}, new String[] {});
 
-        navigateAndCheckOutcome(mFooTestUrl, 0 /* error count before */, 1 /* error count after */);
+        navigateAndCheckOutcome(
+                mFooTestUrl, /* startingErrorCount= */ 0, /* expectedErrorCount= */ 1);
         Assert.assertEquals(
                 WebviewErrorCode.ERROR_CONNECT,
                 mContentsClient.getOnReceivedErrorHelper().getError().errorCode);
@@ -125,10 +127,12 @@
     })
     @OnlyRunIn(SINGLE_PROCESS) // http://crbug.com/660517
     public void testAllowlistedUrl() throws Throwable {
-        navigateAndCheckOutcome(mFooTestUrl, 0 /* error count before */, 0 /* error count after */);
+        navigateAndCheckOutcome(
+                mFooTestUrl, /* startingErrorCount= */ 0, /* expectedErrorCount= */ 0);
 
         // Make sure it goes through the blocklist
-        navigateAndCheckOutcome(mBarTestUrl, 0 /* error count before */, 1 /* error count after */);
+        navigateAndCheckOutcome(
+                mBarTestUrl, /* startingErrorCount= */ 0, /* expectedErrorCount= */ 1);
         Assert.assertEquals(
                 WebviewErrorCode.ERROR_CONNECT,
                 mContentsClient.getOnReceivedErrorHelper().getError().errorCode);
@@ -142,7 +146,8 @@
         @Policies.Item(key = sBlocklistPolicyName, string = "shouldBeAJsonArrayNotAString")
     })
     public void testBadPolicyValue() throws Exception {
-        navigateAndCheckOutcome(mFooTestUrl, 0 /* error count before */, 0 /* error count after */);
+        navigateAndCheckOutcome(
+                mFooTestUrl, /* startingErrorCount= */ 0, /* expectedErrorCount= */ 0);
         // At the moment this test is written, a failure is a crash, a success is no crash.
     }
 
diff --git a/android_webview/js_sandbox/java/src/org/chromium/android_webview/js_sandbox/service/JsSandboxIsolate.java b/android_webview/js_sandbox/java/src/org/chromium/android_webview/js_sandbox/service/JsSandboxIsolate.java
index d1d78196..68560a8 100644
--- a/android_webview/js_sandbox/java/src/org/chromium/android_webview/js_sandbox/service/JsSandboxIsolate.java
+++ b/android_webview/js_sandbox/java/src/org/chromium/android_webview/js_sandbox/service/JsSandboxIsolate.java
@@ -79,7 +79,7 @@
                 throw new IllegalStateException("evaluateJavascript() called after close()");
             }
 
-            Utils.checkAssetFileDescriptor(afd, /*allowUnknownLength=*/true);
+            Utils.checkAssetFileDescriptor(afd, /* allowUnknownLength= */ true);
             if (afd.getLength() > Integer.MAX_VALUE) {
                 throw new IllegalArgumentException("Evaluation code larger than "
                         + Integer.MAX_VALUE + " bytes not supported");
@@ -109,7 +109,7 @@
                         "provideNamedData(String, AssetFileDescriptor) called after close()");
             }
 
-            Utils.checkAssetFileDescriptor(afd, /*allowUnknownLength=*/false);
+            Utils.checkAssetFileDescriptor(afd, /* allowUnknownLength= */ false);
             if (afd.getLength() > Integer.MAX_VALUE) {
                 throw new IllegalArgumentException(
                         "Named data larger than " + Integer.MAX_VALUE + " bytes not supported");
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java
index 781204f..06a063ec 100644
--- a/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java
+++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/FlagsFragment.java
@@ -257,15 +257,18 @@
 
     private static int booleanToBaseFeatureState(Boolean b) {
         if (b == null) {
-            return /* STATE_DEFAULT */ 0;
+            return
+            /* STATE_DEFAULT= */ 0;
         } else if (b) {
-            return /* STATE_ENABLED */ 1;
+            return
+            /* STATE_ENABLED= */ 1;
         }
-        return /* STATE_DISABLED */ 2;
+        return
+        /* STATE_DISABLED= */ 2;
     }
 
     private static int booleanToCommandLineState(Boolean b) {
-        return Boolean.TRUE.equals(b) ? /* STATE_ENABLED */ 1 : /* STATE_DEFAULT */ 0;
+        return Boolean.TRUE.equals(b) ? /* STATE_ENABLED= */ 1 : /* STATE_DEFAULT= */ 0;
     }
 
     private class FlagStateSpinnerSelectedListener implements AdapterView.OnItemSelectedListener {
@@ -546,7 +549,7 @@
      */
     private void formatListEntry(View toggleableFlag, int state) {
         TextView flagName = toggleableFlag.findViewById(R.id.flag_name);
-        if (state == /* STATE_DEFAULT */ 0) {
+        if (state == /* STATE_DEFAULT= */ 0) {
             // Unset the compound drawable.
             flagName.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0);
         } else { // STATE_ENABLED or STATE_DISABLED
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/MainActivity.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/MainActivity.java
index e4445ba4..f387cf4 100644
--- a/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/MainActivity.java
+++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/devui/MainActivity.java
@@ -187,7 +187,7 @@
                         }
                     }
                 },
-                /* recursive */ false);
+                /* recursive= */ false);
 
         // The boolean value doesn't matter, we only care about the total count.
         RecordHistogram.recordBooleanHistogram("Android.WebView.DevUi.AppLaunch", true);
@@ -355,8 +355,9 @@
             return true;
         } else if (item.getItemId() == R.id.options_menu_about_devui) {
             logMenuSelection(MenuChoice.ABOUT_DEVTOOLS);
-            Uri uri = Uri.parse(
-                    "https://chromium.googlesource.com/chromium/src/+/HEAD/android_webview/docs/developer-ui.md");
+            Uri uri =
+                    Uri.parse(
+                            "https://chromium.googlesource.com/chromium/src/+/HEAD/android_webview/docs/developer-ui.md");
             SafeIntentUtils.startActivityOrShowError(this, new Intent(Intent.ACTION_VIEW, uri),
                     SafeIntentUtils.NO_BROWSER_FOUND_ERROR);
             return true;
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/AwPureJavaExceptionReporter.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/AwPureJavaExceptionReporter.java
index 3680bd3..25cf590 100644
--- a/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/AwPureJavaExceptionReporter.java
+++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/nonembedded/AwPureJavaExceptionReporter.java
@@ -19,7 +19,7 @@
     private static boolean sCrashDirMade;
 
     public AwPureJavaExceptionReporter() {
-        super(/*attachLogcat=*/false);
+        super(/* attachLogcat= */ false);
     }
 
     @Override
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java
index 60effa8..7d1cdea 100644
--- a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java
+++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java
@@ -231,7 +231,7 @@
         }
 
         VariationsUtils.debugLog("Scheduling seed download job");
-        scheduleJob(scheduler, requireFastMode, /*requestPeriodicFastMode=*/false);
+        scheduleJob(scheduler, requireFastMode, /* requestPeriodicFastMode= */ false);
     }
 
     private static boolean hasFetchTaskRunRecently() {
@@ -257,7 +257,7 @@
             JobScheduler scheduler, boolean requireFastMode, boolean requestPeriodicFastMode) {
         Context context = ContextUtils.getApplicationContext();
         ComponentName thisComponent = new ComponentName(context, AwVariationsSeedFetcher.class);
-        PersistableBundle extras = new PersistableBundle(/*capacity=*/2);
+        PersistableBundle extras = new PersistableBundle(/* capacity= */ 2);
         extras.putInt(JOB_REQUEST_COUNT_KEY, 0);
         extras.putBoolean(JOB_REQUEST_FAST_MODE, requireFastMode);
         extras.putBoolean(PERIODIC_FAST_MODE, requestPeriodicFastMode);
@@ -320,10 +320,15 @@
                 if (output.getCancelled()) {
                     return null;
                 } else if (fastMode && !periodicFastModeJob) {
-                    scheduleJob(getScheduler(), /*requireFastMode=*/true,
-                            /*requestPeriodicFastMode=*/true);
-                    output = new FetchSeedOutput(/*shouldFinish=*/output.getShouldFinish(),
-                            /*needsReschedule=*/false, /*cancelled=*/output.getCancelled());
+                    scheduleJob(
+                            getScheduler(),
+                            /* requireFastMode= */ true,
+                            /* requestPeriodicFastMode= */ true);
+                    output =
+                            new FetchSeedOutput(
+                                    /* shouldFinish= */ output.getShouldFinish(),
+                                    /* needsReschedule= */ false,
+                                    /* cancelled= */ output.getCancelled());
                     mParams.getExtras().putBoolean(PERIODIC_FAST_MODE, true);
                 }
             } finally {
@@ -379,7 +384,9 @@
 
             if (isCancelled()) {
                 return new FetchSeedOutput(
-                        /*shouldFinish=*/false, /*needsReschedule=*/false, /*cancelled=*/true);
+                        /* shouldFinish= */ false,
+                        /* needsReschedule= */ false,
+                        /* cancelled= */ true);
             }
 
             // VariationsSeedFetcher returns HttpURLConnection.HTTP_NOT_MODIFIED if seed did
@@ -400,13 +407,15 @@
                     VariationsSeedHolder.getInstance().updateSeedFilesSynchronously(
                             fetchInfo.seedInfo);
                 } else {
-                    VariationsSeedHolder.getInstance().updateSeed(fetchInfo.seedInfo,
-                            /*onFinished=*/
-                            () -> onFinished(mParams, /*needsReschedule=*/false));
+                    VariationsSeedHolder.getInstance()
+                            .updateSeed(
+                                    fetchInfo.seedInfo,
+                                    /* onFinished= */ () ->
+                                            onFinished(mParams, /* needsReschedule= */ false));
                     shouldFinish = false; // jobFinished will be deferred until updateSeed is done.
                 }
             }
-            return new FetchSeedOutput(shouldFinish, needsReschedule, /*cancelled=*/false);
+            return new FetchSeedOutput(shouldFinish, needsReschedule, /* cancelled= */ false);
         }
 
         private class FetchSeedOutput {
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/CrashReceiverService.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/CrashReceiverService.java
index 116fb80..1eb821fd 100644
--- a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/CrashReceiverService.java
+++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/CrashReceiverService.java
@@ -36,17 +36,19 @@
     @GuardedBy("mCopyingLock")
     private boolean mIsCopying;
 
-    private final ICrashReceiverService.Stub mBinder = new ICrashReceiverService.Stub() {
-        @Override
-        public void transmitCrashes(ParcelFileDescriptor[] fileDescriptors, List crashInfo) {
-            int uid = Binder.getCallingUid();
-            if (crashInfo != null) {
-                assert crashInfo.size() == fileDescriptors.length;
-            }
-            performMinidumpCopyingSerially(
-                    uid, fileDescriptors, crashInfo, true /* scheduleUploads */);
-        }
-    };
+    private final ICrashReceiverService.Stub mBinder =
+            new ICrashReceiverService.Stub() {
+                @Override
+                public void transmitCrashes(
+                        ParcelFileDescriptor[] fileDescriptors, List crashInfo) {
+                    int uid = Binder.getCallingUid();
+                    if (crashInfo != null) {
+                        assert crashInfo.size() == fileDescriptors.length;
+                    }
+                    performMinidumpCopyingSerially(
+                            uid, fileDescriptors, crashInfo, /* scheduleUploads= */ true);
+                }
+            };
 
     /**
      * Copies minidumps in a synchronized way, waiting for any already started copying operations to
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/MetricsBridgeService.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/MetricsBridgeService.java
index fb0a6253..cbac438 100644
--- a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/MetricsBridgeService.java
+++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/MetricsBridgeService.java
@@ -229,7 +229,7 @@
 
     private FileOutputStream getMetricsLogOutputStream() throws IOException {
         if (mFileOutputStream == null) {
-            mFileOutputStream = new FileOutputStream(getMetricsLogFile(), /* append */ true);
+            mFileOutputStream = new FileOutputStream(getMetricsLogFile(), /* append= */ true);
         }
         return mFileOutputStream;
     }
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/NonEmbeddedFastVariationsSeedSafeModeAction.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/NonEmbeddedFastVariationsSeedSafeModeAction.java
index bd402d1a..15210f3 100644
--- a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/NonEmbeddedFastVariationsSeedSafeModeAction.java
+++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/NonEmbeddedFastVariationsSeedSafeModeAction.java
@@ -27,7 +27,7 @@
 
     @Override
     public boolean onActivate() {
-        AwVariationsSeedFetcher.scheduleIfNeeded(/*requireFastMode=*/true);
+        AwVariationsSeedFetcher.scheduleIfNeeded(/* requireFastMode= */ true);
         return true;
     }
 
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/VariationsSeedHolder.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/VariationsSeedHolder.java
index 31e74fb..7af5448 100644
--- a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/VariationsSeedHolder.java
+++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/VariationsSeedHolder.java
@@ -134,7 +134,7 @@
 
     @VisibleForTesting
     protected VariationsSeedHolder() {
-        mSeedThread = new HandlerThread(/*name=*/"seed_holder");
+        mSeedThread = new HandlerThread(/* name= */ "seed_holder");
         mSeedThread.start();
         mSeedHandler = new Handler(mSeedThread.getLooper());
     }
diff --git a/android_webview/test/embedded_test_server/java/src/org/chromium/android_webview/test/AwEmbeddedTestServer.java b/android_webview/test/embedded_test_server/java/src/org/chromium/android_webview/test/AwEmbeddedTestServer.java
index 1a1e02f..e493559e 100644
--- a/android_webview/test/embedded_test_server/java/src/org/chromium/android_webview/test/AwEmbeddedTestServer.java
+++ b/android_webview/test/embedded_test_server/java/src/org/chromium/android_webview/test/AwEmbeddedTestServer.java
@@ -45,7 +45,7 @@
      *  @return The created server.
      */
     public static AwEmbeddedTestServer createAndStartServer(Context context) {
-        return initializeAndStartServer(new AwEmbeddedTestServer(), context, 0 /* port */);
+        return initializeAndStartServer(new AwEmbeddedTestServer(), context, /* port= */ 0);
     }
 
     /**
@@ -61,6 +61,6 @@
     public static AwEmbeddedTestServer createAndStartHTTPSServer(
             Context context, @ServerCertificate int serverCertificate) {
         return initializeAndStartHTTPSServer(
-                new AwEmbeddedTestServer(), context, serverCertificate, 0 /* port */);
+                new AwEmbeddedTestServer(), context, serverCertificate, /* port= */ 0);
     }
 }
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java b/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java
index a0afa7d..c50e516 100644
--- a/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java
+++ b/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellActivity.java
@@ -230,10 +230,13 @@
                     AwBrowserContext.getDefault().getNativeBrowserContextPointer());
         }
         final AwSettings awSettings =
-                new AwSettings(this /* context */, false /* isAccessFromFileURLsGrantedByDefault */,
-                        false /* supportsLegacyQuirks */, false /* allowEmptyDocumentPersistence */,
-                        true /* allowGeolocationOnInsecureOrigins */,
-                        false /* doNotUpdateSelectionOnMutatingSelectionRange */);
+                new AwSettings(
+                        /* context= */ this,
+                        /* isAccessFromFileURLsGrantedByDefault= */ false,
+                        /* supportsLegacyQuirks= */ false,
+                        /* allowEmptyDocumentPersistence= */ false,
+                        /* allowGeolocationOnInsecureOrigins= */ true,
+                        /* doNotUpdateSelectionOnMutatingSelectionRange= */ false);
         // Required for WebGL conformance tests.
         awSettings.setMediaPlaybackRequiresUserGesture(false);
         // Allow zoom and fit contents to screen
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java b/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java
index 6ff4125a..16656c0b 100644
--- a/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java
+++ b/android_webview/test/shell/src/org/chromium/android_webview/test/AwTestContainerView.java
@@ -112,10 +112,16 @@
         }
 
         public void readbackQuadrantColors(Callback<int[]> callback) {
-            sRenderThreadHandler.post(() -> {
-                callback.onResult(mContextManager.draw(
-                        mWidth, mHeight, mLastScrollX, mLastScrollY, /*readbackQuadrants=*/true));
-            });
+            sRenderThreadHandler.post(
+                    () -> {
+                        callback.onResult(
+                                mContextManager.draw(
+                                        mWidth,
+                                        mHeight,
+                                        mLastScrollX,
+                                        mLastScrollY,
+                                        /* readbackQuadrants= */ true));
+                    });
         }
 
         public boolean isReadyToRender() {
@@ -198,7 +204,7 @@
                 int scrollX, int scrollY) {
             mContextManager.sync(functor, false);
             syncEvent.signal();
-            mContextManager.draw(width, height, scrollX, scrollY, /*readbackQuadrants=*/false);
+            mContextManager.draw(width, height, scrollX, scrollY, /* readbackQuadrants= */ false);
         }
     }
 
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/test/NullContentsClient.java b/android_webview/test/shell/src/org/chromium/android_webview/test/NullContentsClient.java
index 198ae54..9bbddbcb 100644
--- a/android_webview/test/shell/src/org/chromium/android_webview/test/NullContentsClient.java
+++ b/android_webview/test/shell/src/org/chromium/android_webview/test/NullContentsClient.java
@@ -178,8 +178,9 @@
     @Override
     public void onSafeBrowsingHit(AwWebResourceRequest request, int threatType,
             Callback<AwSafeBrowsingResponse> callback) {
-        callback.onResult(new AwSafeBrowsingResponse(SafeBrowsingAction.SHOW_INTERSTITIAL,
-                /* reporting */ true));
+        callback.onResult(
+                new AwSafeBrowsingResponse(
+                        SafeBrowsingAction.SHOW_INTERSTITIAL, /* reporting= */ true));
     }
 
     @Override
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/test/SecondBrowserProcess.java b/android_webview/test/shell/src/org/chromium/android_webview/test/SecondBrowserProcess.java
index 74e8f70..ca011e2 100644
--- a/android_webview/test/shell/src/org/chromium/android_webview/test/SecondBrowserProcess.java
+++ b/android_webview/test/shell/src/org/chromium/android_webview/test/SecondBrowserProcess.java
@@ -52,7 +52,7 @@
     private void startBrowserProcess() {
         AwResource.setResources(this.getResources());
         AwResource.setConfigKeySystemUuidMapping(R.array.config_key_system_uuid_mapping);
-        AwTestContainerView.installDrawFnFunctionTable(/*useVulkan=*/false);
+        AwTestContainerView.installDrawFnFunctionTable(/* useVulkan= */ false);
         AwBrowserProcess.loadLibrary(null);
         AwBrowserProcess.start();
     }
diff --git a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewLayoutTestActivity.java b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewLayoutTestActivity.java
index 3ba40bb..464ecc3 100644
--- a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewLayoutTestActivity.java
+++ b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewLayoutTestActivity.java
@@ -62,45 +62,50 @@
             }
         });
 
-        mWebView.setWebChromeClient(new WebChromeClient() {
-            @Override
-            public void onGeolocationPermissionsShowPrompt(String origin,
-                    GeolocationPermissions.Callback callback) {
-                mConsoleLog.append("onGeolocationPermissionsShowPrompt" + "\n");
-                if (mGrantPermission) {
-                    mConsoleLog.append("geolocation request granted" + "\n");
-                    callback.invoke(origin, true /* allow */, false);
-                } else {
-                    mConsoleLog.append("geolocation request denied" + "\n");
-                    callback.invoke(origin, false /* allow */, false);
-                }
-            }
+        mWebView.setWebChromeClient(
+                new WebChromeClient() {
+                    @Override
+                    public void onGeolocationPermissionsShowPrompt(
+                            String origin, GeolocationPermissions.Callback callback) {
+                        mConsoleLog.append("onGeolocationPermissionsShowPrompt" + "\n");
+                        if (mGrantPermission) {
+                            mConsoleLog.append("geolocation request granted" + "\n");
+                            callback.invoke(origin, /* allow= */ true, false);
+                        } else {
+                            mConsoleLog.append("geolocation request denied" + "\n");
+                            callback.invoke(origin, /* allow= */ false, false);
+                        }
+                    }
 
-            @Override
-            @SuppressLint("NewApi") // PermissionRequest#deny requires API level 21.
-            public void onPermissionRequest(PermissionRequest request) {
-                mConsoleLog.append("onPermissionRequest: "
-                        + TextUtils.join(",", request.getResources()) + "\n");
-                if (mGrantPermission) {
-                    mConsoleLog.append("request granted: "
-                            + TextUtils.join(",", request.getResources()) + "\n");
-                    request.grant(request.getResources());
-                } else {
-                    mConsoleLog.append("request denied" + "\n");
-                    request.deny();
-                }
-            }
+                    @Override
+                    @SuppressLint("NewApi") // PermissionRequest#deny requires API level 21.
+                    public void onPermissionRequest(PermissionRequest request) {
+                        mConsoleLog.append(
+                                "onPermissionRequest: "
+                                        + TextUtils.join(",", request.getResources())
+                                        + "\n");
+                        if (mGrantPermission) {
+                            mConsoleLog.append(
+                                    "request granted: "
+                                            + TextUtils.join(",", request.getResources())
+                                            + "\n");
+                            request.grant(request.getResources());
+                        } else {
+                            mConsoleLog.append("request denied" + "\n");
+                            request.deny();
+                        }
+                    }
 
-            @Override
-            public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
-                // TODO(timvolodine): put log and warnings in separate string builders.
-                mConsoleLog.append(consoleMessage.message() + "\n");
-                if (consoleMessage.message().equals(TEST_FINISHED_SENTINEL)) {
-                    finishTest();
-                }
-                return true;
-            }
-        });
+                    @Override
+                    public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
+                        // TODO(timvolodine): put log and warnings in separate string builders.
+                        mConsoleLog.append(consoleMessage.message() + "\n");
+                        if (consoleMessage.message().equals(TEST_FINISHED_SENTINEL)) {
+                            finishTest();
+                        }
+                        return true;
+                    }
+                });
 
         // The WebView permissions layout tests depend on results from the console and permissions
         // logs which is highly order specific.
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd
index 2b4bc28..36500a8 100644
--- a/ash/ash_strings.grd
+++ b/ash/ash_strings.grd
@@ -300,11 +300,10 @@
         <ph name="battery">$2<ex>Battery is full.</ex></ph>
         <ph name="channel">$3<ex>Stable Channel</ex></ph>
         <ph name="network">$4<ex>Connected to Wifi.</ex></ph>,
-        <ph name="privacy">$5<ex>Camera in use</ex></ph>,
-        <ph name="managed">$6<ex>This account is managed by Family Link</ex></ph>
-        <ph name="notification">$7<ex>1 notification</ex></ph>,
-        <ph name="ime">$8<ex>Using US keyboard</ex></ph>
-        <ph name="locale">$9<ex>Using English</ex></ph>
+        <ph name="managed">$5<ex>This account is managed by Family Link</ex></ph>
+        <ph name="notification">$6<ex>1 notification</ex></ph>,
+        <ph name="ime">$7<ex>Using US keyboard</ex></ph>
+        <ph name="locale">$8<ex>Using English</ex></ph>
       </message>
       <message name="IDS_ASH_STATUS_TRAY_NETWORK_ACCESSIBLE_DESCRIPTION" is_accessibility_with_no_ui="true" desc="The accessible description of hotspot and network in the status tray and the information on it.">
         <ph name="hotspot">$1<ex>Hotspot on, no devices connected</ex></ph>,
diff --git a/ash/capture_mode/capture_mode_camera_unittests.cc b/ash/capture_mode/capture_mode_camera_unittests.cc
index b27ddb85..8dd0fbe 100644
--- a/ash/capture_mode/capture_mode_camera_unittests.cc
+++ b/ash/capture_mode/capture_mode_camera_unittests.cc
@@ -4728,15 +4728,10 @@
 
   PrivacyIndicatorsTrayItemView* GetPrimaryDisplayPrivacyIndicatorsView()
       const {
-    return features::IsQsRevampEnabled()
-               ? Shell::GetPrimaryRootWindowController()
-                     ->GetStatusAreaWidget()
-                     ->notification_center_tray()
-                     ->privacy_indicators_view()
-               : Shell::GetPrimaryRootWindowController()
-                     ->GetStatusAreaWidget()
-                     ->unified_system_tray()
-                     ->privacy_indicators_view();
+    return Shell::GetPrimaryRootWindowController()
+        ->GetStatusAreaWidget()
+        ->notification_center_tray()
+        ->privacy_indicators_view();
   }
 
   // TODO(b/305075031) clean up after the flag is removed.
diff --git a/ash/capture_mode/capture_mode_util.cc b/ash/capture_mode/capture_mode_util.cc
index a77f396..a84954b 100644
--- a/ash/capture_mode/capture_mode_util.cc
+++ b/ash/capture_mode/capture_mode_util.cc
@@ -520,7 +520,8 @@
 }
 
 void MaybeUpdateCaptureModePrivacyIndicators() {
-  if (!features::IsPrivacyIndicatorsEnabled()) {
+  // Privacy indicator is only enabled when Video Conference is disabled.
+  if (features::IsVideoConferenceEnabled()) {
     return;
   }
 
diff --git a/ash/components/arc/session/arc_vm_client_adapter_unittest.cc b/ash/components/arc/session/arc_vm_client_adapter_unittest.cc
index d5d41be..3a26c6d7 100644
--- a/ash/components/arc/session/arc_vm_client_adapter_unittest.cc
+++ b/ash/components/arc/session/arc_vm_client_adapter_unittest.cc
@@ -1688,7 +1688,7 @@
 
 // Tests that the binary translation type is set to None when no library is
 // enabled by USE flags.
-TEST_F(ArcVmClientAdapterTest, BintaryTranslationTypeNone) {
+TEST_F(ArcVmClientAdapterTest, BinaryTranslationTypeNone) {
   StartParams start_params(GetPopulatedStartParams());
   StartMiniArcWithParams(true, std::move(start_params));
   const auto& request = GetTestConciergeClient()->start_arc_vm_request();
@@ -1699,7 +1699,7 @@
 
 // Tests that the binary translation type is set to Houdini when only 32-bit
 // Houdini library is enabled by USE flags.
-TEST_F(ArcVmClientAdapterTest, BintaryTranslationTypeHoudini) {
+TEST_F(ArcVmClientAdapterTest, BinaryTranslationTypeHoudini) {
   base::CommandLine::ForCurrentProcess()->InitFromArgv(
       {"", "--enable-houdini"});
   StartParams start_params(GetPopulatedStartParams());
@@ -1712,7 +1712,7 @@
 
 // Tests that the binary translation type is set to Houdini when only 64-bit
 // Houdini library is enabled by USE flags.
-TEST_F(ArcVmClientAdapterTest, BintaryTranslationTypeHoudini64) {
+TEST_F(ArcVmClientAdapterTest, BinaryTranslationTypeHoudini64) {
   base::CommandLine::ForCurrentProcess()->InitFromArgv(
       {"", "--enable-houdini64"});
   StartParams start_params(GetPopulatedStartParams());
@@ -1725,7 +1725,7 @@
 
 // Tests that the binary translation type is set to NDK translation when only
 // 32-bit NDK translation library is enabled by USE flags.
-TEST_F(ArcVmClientAdapterTest, BintaryTranslationTypeNdkTranslation) {
+TEST_F(ArcVmClientAdapterTest, BinaryTranslationTypeNdkTranslation) {
   base::CommandLine::ForCurrentProcess()->InitFromArgv(
       {"", "--enable-ndk-translation"});
   StartParams start_params(GetPopulatedStartParams());
@@ -1738,7 +1738,7 @@
 
 // Tests that the binary translation type is set to NDK translation when only
 // 64-bit NDK translation library is enabled by USE flags.
-TEST_F(ArcVmClientAdapterTest, BintaryTranslationTypeNdkTranslation64) {
+TEST_F(ArcVmClientAdapterTest, BinaryTranslationTypeNdkTranslation64) {
   base::CommandLine::ForCurrentProcess()->InitFromArgv(
       {"", "--enable-ndk-translation64"});
   StartParams start_params(GetPopulatedStartParams());
@@ -1752,7 +1752,7 @@
 // Tests that the binary translation type is set to NDK translation when both
 // Houdini and NDK translation libraries are enabled by USE flags, and the
 // parameter start_params.native_bridge_experiment is set to true.
-TEST_F(ArcVmClientAdapterTest, BintaryTranslationTypeNativeBridgeExperiment) {
+TEST_F(ArcVmClientAdapterTest, BinaryTranslationTypeNativeBridgeExperiment) {
   base::CommandLine::ForCurrentProcess()->InitFromArgv(
       {"", "--enable-houdini", "--enable-ndk-translation"});
   StartParams start_params(GetPopulatedStartParams());
@@ -1767,7 +1767,7 @@
 // Tests that the binary translation type is set to Houdini when both Houdini
 // and NDK translation libraries are enabled by USE flags, and the parameter
 // start_params.native_bridge_experiment is set to false.
-TEST_F(ArcVmClientAdapterTest, BintaryTranslationTypeNoNativeBridgeExperiment) {
+TEST_F(ArcVmClientAdapterTest, BinaryTranslationTypeNoNativeBridgeExperiment) {
   base::CommandLine::ForCurrentProcess()->InitFromArgv(
       {"", "--enable-houdini", "--enable-ndk-translation"});
   StartParams start_params(GetPopulatedStartParams());
@@ -2380,6 +2380,14 @@
   EXPECT_FALSE(request.mini_instance_request().enable_privacy_hub_for_chrome());
 }
 
+TEST_F(ArcVmClientAdapterTest, StartMiniArc_ArcSwitchToKeymint_Default) {
+  StartMiniArc();
+  EXPECT_GE(GetTestConciergeClient()->start_arc_vm_call_count(), 1);
+  EXPECT_FALSE(is_system_shutdown().has_value());
+  const auto& request = GetTestConciergeClient()->start_arc_vm_request();
+  EXPECT_FALSE(request.mini_instance_request().arc_switch_to_keymint());
+}
+
 // Test that the value of swappiness is default value when kGuestZram is
 // disabled.
 TEST_F(ArcVmClientAdapterTest, ArcGuestZramDisabledSwappiness) {
diff --git a/ash/components/arc/test/fake_file_system_instance.cc b/ash/components/arc/test/fake_file_system_instance.cc
index 17a5e78..84bd9560 100644
--- a/ash/components/arc/test/fake_file_system_instance.cc
+++ b/ash/components/arc/test/fake_file_system_instance.cc
@@ -12,6 +12,7 @@
 #include <utility>
 
 #include "base/containers/contains.h"
+#include "base/containers/cxx20_erase_vector.h"
 #include "base/files/file.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -600,6 +601,12 @@
   documents_.erase(iter);
   size_t erased = child_documents_.erase(key);
   DCHECK_NE(0u, erased);
+
+  // Remove this document from lists of children.
+  for (auto& child_iter : child_documents_) {
+    base::Erase(child_iter.second, key);
+  }
+
   base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
       FROM_HERE, base::BindOnce(std::move(callback), true));
 }
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index 4dfa249..17867586 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -300,12 +300,6 @@
              "BluetoothQualityReport",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-// Enables or disables Bluetooth WBS microphone be selected as default
-// audio input option.
-BASE_FEATURE(kBluetoothWbsDogfood,
-             "BluetoothWbsDogfood",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
 BASE_FEATURE(kRobustAudioDeviceSelectLogic,
              "RobustAudioDeviceSelectLogic",
              base::FEATURE_ENABLED_BY_DEFAULT);
@@ -1992,6 +1986,9 @@
              "OverviewDeskNavigation",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
+// Enables the updated Palette feature.
+BASE_FEATURE(kPalette, "Palette", base::FEATURE_DISABLED_BY_DEFAULT);
+
 // Enables Jelly colors and components to appear in the Parent Access Widget
 // if jelly-colors is also enabled.
 BASE_FEATURE(kParentAccessJelly,
@@ -2645,6 +2642,13 @@
              "TimeOfDayWallpaper",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
+// Forces the time of day wallpaper to change on an automatic sunset-to-sunrise
+// schedule, regardless of what dark/light mode settings are active.
+// Not used if time of day wallpaper is not enabled.
+BASE_FEATURE(kTimeOfDayWallpaperForcedAutoSchedule,
+             "TimeOfDayWallpaperForcedAutoSchedule",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 // Enables retrieving time of day screen saver assets from DLC, rather than from
 // rootfs.
 BASE_FEATURE(kTimeOfDayDlc, "TimeOfDayDlc", base::FEATURE_DISABLED_BY_DEFAULT);
@@ -2966,7 +2970,7 @@
 // ShouldUseMappableSharedImage() below.
 BASE_FEATURE(kEnableMappableSIForFastInkHost,
              "EnableMappableSIForFastInkHost",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -4220,6 +4224,11 @@
          base::FeatureList::IsEnabled(kFeatureManagementTimeOfDayWallpaper);
 }
 
+bool IsTimeOfDayWallpaperForcedAutoScheduleEnabled() {
+  return IsTimeOfDayWallpaperEnabled() &&
+         base::FeatureList::IsEnabled(kTimeOfDayWallpaperForcedAutoSchedule);
+}
+
 bool IsTimeOfDayDlcEnabled() {
   return IsTimeOfDayScreenSaverEnabled() &&
          base::FeatureList::IsEnabled(kTimeOfDayDlc);
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index 0a28f90..be336f6 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -85,7 +85,6 @@
 COMPONENT_EXPORT(ASH_CONSTANTS)
 BASE_DECLARE_FEATURE(kBluetoothFixA2dpPacketSize);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kBluetoothQualityReport);
-COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kBluetoothWbsDogfood);
 COMPONENT_EXPORT(ASH_CONSTANTS)
 BASE_DECLARE_FEATURE(kRobustAudioDeviceSelectLogic);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kBorealisBigGl);
@@ -603,6 +602,7 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kOsSyncConsentRevamp);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kOverviewButton);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kOverviewDeskNavigation);
+COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPalette);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kParentAccessJelly);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPasspointARCSupport);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPasspointSettings);
@@ -805,6 +805,8 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kTerminalDev);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kTimeOfDayScreenSaver);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kTimeOfDayWallpaper);
+COMPONENT_EXPORT(ASH_CONSTANTS)
+BASE_DECLARE_FEATURE(kTimeOfDayWallpaperForcedAutoSchedule);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kTimeOfDayDlc);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kTrafficCountersEnabled);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kTrilinearFiltering);
@@ -1213,6 +1215,8 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsStylusBatteryStatusEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsTimeOfDayScreenSaverEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsTimeOfDayWallpaperEnabled();
+COMPONENT_EXPORT(ASH_CONSTANTS)
+bool IsTimeOfDayWallpaperForcedAutoScheduleEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsTimeOfDayDlcEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsTabClusterUIEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsTouchpadInDiagnosticsAppEnabled();
diff --git a/ash/constants/ash_pref_names.h b/ash/constants/ash_pref_names.h
index 768e3814..832544b1 100644
--- a/ash/constants/ash_pref_names.h
+++ b/ash/constants/ash_pref_names.h
@@ -1594,6 +1594,10 @@
 // An boolean pref that indicates whether background replacement is applied.
 inline constexpr char kBackgroundReplace[] = "ash.camera.background_replace";
 
+// An string pref that indicates the image path of the camera background.
+inline constexpr char kBackgroundImagePath[] =
+    "ash.camera.background_image_path";
+
 // An boolean pref that indicates whether portrait relighting is applied.
 inline constexpr char kPortraitRelighting[] = "ash.camera.portrait_relighting";
 
diff --git a/ash/constants/notifier_catalogs.h b/ash/constants/notifier_catalogs.h
index dacafef..c3caef1 100644
--- a/ash/constants/notifier_catalogs.h
+++ b/ash/constants/notifier_catalogs.h
@@ -79,7 +79,7 @@
   kBluetoothPairingRequest = 64,
   // [Deprecated] kBluetoothPairedDevice = 65,
   kCellularSetup = 66,
-  kScreenSecurity = 67,
+  // [Deprecated] kScreenSecurity = 67,
   kWifiToggle = 68,
   kUSBPeripheralInvalidDpCable = 69,
   kUSBPeripheralInvalidUSB4ValidTBTCable = 70,
diff --git a/ash/debug.cc b/ash/debug.cc
index f4895e9..460a92ce 100644
--- a/ash/debug.cc
+++ b/ash/debug.cc
@@ -39,13 +39,18 @@
 }
 
 void PrintLayerHierarchy(std::ostringstream* out) {
+  ui::DebugLayerChildCallback child_cb =
+      instance ? base::BindRepeating(
+                     &DebugWindowHierarchyDelegate::GetAdjustedLayerChildren,
+                     base::Unretained(instance.get()))
+               : ui::DebugLayerChildCallback();
   for (aura::Window* root : Shell::Get()->GetAllRootWindows()) {
     ui::Layer* layer = root->layer();
     if (layer) {
       ui::PrintLayerHierarchy(
           layer,
           RootWindowController::ForWindow(root)->GetLastMouseLocationInRoot(),
-          out);
+          out, child_cb);
     }
   }
 }
@@ -127,7 +132,8 @@
   }
 
   std::vector<aura::Window*> children =
-      instance ? instance->GetAdjustedChildren(window) : window->children();
+      instance ? instance->GetAdjustedWindowChildren(window)
+               : window->children();
   for (aura::Window* child : children) {
     PrintWindowHierarchy(active_window, focused_window, capture_window, child,
                          indent + 3, scrub_data, out_window_titles, out);
diff --git a/ash/fast_ink/fast_ink_host.h b/ash/fast_ink/fast_ink_host.h
index 5d4c96c..4d5680db 100644
--- a/ash/fast_ink/fast_ink_host.h
+++ b/ash/fast_ink/fast_ink_host.h
@@ -71,6 +71,10 @@
 
   const gpu::Mailbox& mailbox_for_test() const { return mailbox_; }
 
+  viz::RasterContextProvider* context_provider_for_test() {
+    return context_provider_.get();
+  }
+
   int get_pending_bitmaps_size_for_test() const {
     return pending_bitmaps_.size();
   }
diff --git a/ash/fast_ink/fast_ink_host_unittest.cc b/ash/fast_ink/fast_ink_host_unittest.cc
index 67d0019..9d99a30 100644
--- a/ash/fast_ink/fast_ink_host_unittest.cc
+++ b/ash/fast_ink/fast_ink_host_unittest.cc
@@ -41,9 +41,13 @@
 
 class FastInkHostTest
     : public AshTestBase,
-      public ::testing::WithParamInterface<
-          std::
-              tuple<std::string, bool, gfx::Rect, gfx::Rect, gfx::Rect, bool>> {
+      public ::testing::WithParamInterface<std::tuple<std::string,
+                                                      bool,
+                                                      gfx::Rect,
+                                                      gfx::Rect,
+                                                      gfx::Rect,
+                                                      bool,
+                                                      bool>> {
  public:
   FastInkHostTest()
       : first_display_specs_(std::get<0>(GetParam())),
@@ -51,7 +55,8 @@
         content_rect_(std::get<2>(GetParam())),
         expected_quad_rect_(std::get<3>(GetParam())),
         expected_quad_layer_rect_(std::get<4>(GetParam())),
-        use_one_si_for_fast_ink_host_resources_(std::get<5>(GetParam())) {
+        use_one_si_for_fast_ink_host_resources_(std::get<5>(GetParam())),
+        enable_mappable_si_for_fast_ink_host_(std::get<6>(GetParam())) {
     std::vector<base::test::FeatureRef> enabled_features = {};
     std::vector<base::test::FeatureRef> disabled_features = {};
     if (use_one_si_for_fast_ink_host_resources_) {
@@ -62,6 +67,12 @@
           features::kUseOneSharedImageForFastInkHostResources);
     }
 
+    if (enable_mappable_si_for_fast_ink_host_) {
+      enabled_features.push_back(features::kEnableMappableSIForFastInkHost);
+    } else {
+      disabled_features.push_back(features::kEnableMappableSIForFastInkHost);
+    }
+
     scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
   }
 
@@ -113,6 +124,7 @@
   gfx::Rect expected_quad_rect_;
   gfx::Rect expected_quad_layer_rect_;
   bool use_one_si_for_fast_ink_host_resources_;
+  bool enable_mappable_si_for_fast_ink_host_;
 
   std::unique_ptr<views::Widget> widget_;
   raw_ptr<aura::Window, DanglingUntriaged> host_window_;
@@ -201,24 +213,42 @@
   // Request the first frame.
   OnBeginFrame();
 
-  // Buffer should be initialized after receiving the first begin frame.
-  gfx::GpuMemoryBuffer* gpu_memory_buffer =
-      fast_ink_host_->gpu_memory_buffer_for_test();
-  if (use_one_si_for_fast_ink_host_resources_) {
-    ASSERT_FALSE(fast_ink_host_->mailbox_for_test().IsZero());
+  bool should_be_using_gmb = !use_one_si_for_fast_ink_host_resources_ ||
+                             !enable_mappable_si_for_fast_ink_host_;
+
+  if (should_be_using_gmb) {
+    // Buffer should be initialized after receiving the first begin frame.
+    gfx::GpuMemoryBuffer* gpu_memory_buffer =
+        fast_ink_host_->gpu_memory_buffer_for_test();
+    if (use_one_si_for_fast_ink_host_resources_) {
+      ASSERT_FALSE(fast_ink_host_->mailbox_for_test().IsZero());
+    } else {
+      ASSERT_TRUE(fast_ink_host_->mailbox_for_test().IsZero());
+    }
+
+    ASSERT_TRUE(gpu_memory_buffer);
+    // Pending bitmaps should be drawn and cleared.
+    EXPECT_EQ(fast_ink_host_->get_pending_bitmaps_size_for_test(), 0);
+
+    ASSERT_TRUE(gpu_memory_buffer->Map());
+    // Pending bitmaps should be correctly copied to the gpu memory buffer.
+    EXPECT_EQ(*static_cast<SkColor*>(gpu_memory_buffer->memory(0)),
+              SK_ColorGREEN);
+    gpu_memory_buffer->Unmap();
   } else {
-    ASSERT_TRUE(fast_ink_host_->mailbox_for_test().IsZero());
+    // MappableSI should be initialized after receiving the first begin frame.
+    gpu::Mailbox mailbox = fast_ink_host_->mailbox_for_test();
+    ASSERT_FALSE(mailbox.IsZero());
+    // Pending bitmaps should be drawn and cleared.
+    EXPECT_EQ(fast_ink_host_->get_pending_bitmaps_size_for_test(), 0);
+
+    auto mapping = fast_ink_host_->context_provider_for_test()
+                       ->SharedImageInterface()
+                       ->MapSharedImage(mailbox);
+    ASSERT_TRUE(mapping);
+    // Pending bitmaps should be correctly copied to the MappableSI's buffer.
+    EXPECT_EQ(*static_cast<SkColor*>(mapping->Memory(0)), SK_ColorGREEN);
   }
-
-  ASSERT_TRUE(gpu_memory_buffer);
-  // Pending bitmaps should be drawn and cleared.
-  EXPECT_EQ(fast_ink_host_->get_pending_bitmaps_size_for_test(), 0);
-
-  ASSERT_TRUE(gpu_memory_buffer->Map());
-  // Pending bitmaps should be correctly copied to the gpu memory buffer.
-  EXPECT_EQ(*static_cast<SkColor*>(gpu_memory_buffer->memory(0)),
-            SK_ColorGREEN);
-  gpu_memory_buffer->Unmap();
 }
 
 INSTANTIATE_TEST_SUITE_P(
@@ -233,7 +263,8 @@
             /*content_rect=*/gfx::Rect(10, 10),
             /*expected_quad_rect=*/gfx::Rect(0, 0, 1000, 500),
             /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 1000, 500),
-            /*use_one_si_for_fast_ink_host_resources=*/false),
+            /*use_one_si_for_fast_ink_host_resources=*/false,
+            /*enable_mappable_si_for_fast_ink_host=*/false),
         // Run a test with `use_one_si_for_fast_ink_host_resources` set to true.
         std::make_tuple(
             /*first_display_specs=*/"1000x500",
@@ -241,21 +272,43 @@
             /*content_rect=*/gfx::Rect(10, 10),
             /*expected_quad_rect=*/gfx::Rect(0, 0, 1000, 500),
             /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 1000, 500),
-            /*use_one_si_for_fast_ink_host_resources=*/true),
+            /*use_one_si_for_fast_ink_host_resources=*/true,
+            /*enable_mappable_si_for_fast_ink_host=*/false),
+        // Run a test to verify that MappableSI is not used if we are not using
+        // a single SharedImage for FastInkHost UiResources.
+        std::make_tuple(
+            /*first_display_specs=*/"1000x500",
+            /*auto_update=*/true,
+            /*content_rect=*/gfx::Rect(10, 10),
+            /*expected_quad_rect=*/gfx::Rect(0, 0, 1000, 500),
+            /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 1000, 500),
+            /*use_one_si_for_fast_ink_host_resources=*/false,
+            /*enable_mappable_si_for_fast_ink_host=*/true),
+        // Run a test with MappableSI used.
+        std::make_tuple(
+            /*first_display_specs=*/"1000x500",
+            /*auto_update=*/true,
+            /*content_rect=*/gfx::Rect(10, 10),
+            /*expected_quad_rect=*/gfx::Rect(0, 0, 1000, 500),
+            /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 1000, 500),
+            /*use_one_si_for_fast_ink_host_resources=*/true,
+            /*enable_mappable_si_for_fast_ink_host=*/true),
         std::make_tuple(
             /*first_display_specs=*/"1000x500*2",
             /*auto_update=*/true,
             /*content_rect=*/gfx::Rect(10, 10),
             /*expected_quad_rect=*/gfx::Rect(0, 0, 1000, 500),
             /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 1000, 500),
-            /*use_one_si_for_fast_ink_host_resources=*/false),
+            /*use_one_si_for_fast_ink_host_resources=*/false,
+            /*enable_mappable_si_for_fast_ink_host=*/false),
         std::make_tuple(
             /*first_display_specs=*/"1000x500*2/r",
             /*auto_update=*/true,
             /*content_rect=*/gfx::Rect(10, 10),
             /*expected_quad_rect=*/gfx::Rect(0, 0, 1000, 500),
             /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 500, 1000),
-            /*use_one_si_for_fast_ink_host_resources=*/false),
+            /*use_one_si_for_fast_ink_host_resources=*/false,
+            /*enable_mappable_si_for_fast_ink_host=*/false),
         // When auto updating is off, we update the surface enclosed by
         // content_rect.
         std::make_tuple(
@@ -264,21 +317,24 @@
             /*content_rect=*/gfx::Rect(10, 10),
             /*expected_quad_rect=*/gfx::Rect(0, 0, 10, 10),
             /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 1000, 500),
-            /*use_one_si_for_fast_ink_host_resources=*/false),
+            /*use_one_si_for_fast_ink_host_resources=*/false,
+            /*enable_mappable_si_for_fast_ink_host=*/false),
         std::make_tuple(
             /*first_display_specs=*/"1000x500*2",
             /*auto_update=*/false,
             /*content_rect=*/gfx::Rect(10, 10),
             /*expected_quad_rect=*/gfx::Rect(0, 0, 20, 20),
             /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 1000, 500),
-            /*use_one_si_for_fast_ink_host_resources=*/false),
+            /*use_one_si_for_fast_ink_host_resources=*/false,
+            /*enable_mappable_si_for_fast_ink_host=*/false),
         std::make_tuple(
             /*first_display_specs=*/"1000x500*2/l",
             /*auto_update=*/false,
             /*content_rect=*/gfx::Rect(10, 15),
             /*expected_quad_rect=*/gfx::Rect(0, 480, 30, 20),
             /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 500, 1000),
-            /*use_one_si_for_fast_ink_host_resources=*/false),
+            /*use_one_si_for_fast_ink_host_resources=*/false,
+            /*enable_mappable_si_for_fast_ink_host=*/false),
         // If content rect is partially outside of the buffer, quad rect is
         // clipped by buffer size.
         std::make_tuple(
@@ -287,7 +343,8 @@
             /*content_rect=*/gfx::Rect(995, 0, 10, 10),
             /*expected_quad_rect=*/gfx::Rect(995, 0, 5, 10),
             /*expected_quad_layer_rect=*/gfx::Rect(0, 0, 1000, 500),
-            /*use_one_si_for_fast_ink_host_resources=*/false)));
+            /*use_one_si_for_fast_ink_host_resources=*/false,
+            /*enable_mappable_si_for_fast_ink_host=*/false)));
 
 }  // namespace
 }  // namespace ash
diff --git a/ash/public/cpp/debug_utils.h b/ash/public/cpp/debug_utils.h
index e64eab5f..ebe8b4e 100644
--- a/ash/public/cpp/debug_utils.h
+++ b/ash/public/cpp/debug_utils.h
@@ -15,14 +15,21 @@
 class Window;
 }  // namespace aura
 
+namespace ui {
+class Layer;
+}  // namespace ui
+
 namespace ash {
 namespace debug {
 
 class ASH_EXPORT DebugWindowHierarchyDelegate {
  public:
   virtual ~DebugWindowHierarchyDelegate() = default;
-  virtual std::vector<aura::Window*> GetAdjustedChildren(
+  virtual std::vector<aura::Window*> GetAdjustedWindowChildren(
       aura::Window* window) const = 0;
+
+  virtual std::vector<ui::Layer*> GetAdjustedLayerChildren(
+      const ui::Layer* layer) const = 0;
 };
 
 ASH_EXPORT void SetDebugWindowHierarchyDelegate(
diff --git a/ash/public/cpp/shelf_item.h b/ash/public/cpp/shelf_item.h
index 57005b4..2b62097 100644
--- a/ash/public/cpp/shelf_item.h
+++ b/ash/public/cpp/shelf_item.h
@@ -27,6 +27,8 @@
 
   // Image to display in the shelf.
   gfx::ImageSkia image;
+  // Whether the image for this shelf item is a placeholder image.
+  bool has_placeholder_icon;
 
   // If set, an image to be displayed as a badge on the main shelf image.
   gfx::ImageSkia badge_image;
diff --git a/ash/public/cpp/test/mock_projector_client.cc b/ash/public/cpp/test/mock_projector_client.cc
index 9034709f..49e0db5 100644
--- a/ash/public/cpp/test/mock_projector_client.cc
+++ b/ash/public/cpp/test/mock_projector_client.cc
@@ -4,6 +4,8 @@
 
 #include "ash/public/cpp/test/mock_projector_client.h"
 
+#include "base/check.h"
+
 namespace ash {
 
 MockProjectorClient::MockProjectorClient() {
diff --git a/ash/resources/vector_icons/BUILD.gn b/ash/resources/vector_icons/BUILD.gn
index 4d680fb1..b97bf32 100644
--- a/ash/resources/vector_icons/BUILD.gn
+++ b/ash/resources/vector_icons/BUILD.gn
@@ -267,7 +267,6 @@
     "notification_monitor_warning.icon",
     "notification_multi_device_setup.icon",
     "notification_screen.icon",
-    "notification_screenshare.icon",
     "notification_sms_sync.icon",
     "notification_snooze_button.icon",
     "notification_stylus_battery_warning.icon",
diff --git a/ash/resources/vector_icons/notification_screenshare.icon b/ash/resources/vector_icons/notification_screenshare.icon
deleted file mode 100644
index b9b63dd..0000000
--- a/ash/resources/vector_icons/notification_screenshare.icon
+++ /dev/null
@@ -1,29 +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.
-
-CANVAS_DIMENSIONS, 96,
-MOVE_TO, 16, 18,
-R_H_LINE_TO, 64,
-R_CUBIC_TO, 4.42f, 0, 8, 3.58f, 8, 8,
-R_V_LINE_TO, 44,
-R_CUBIC_TO, 0, 4.42f, -3.58f, 8, -8, 8,
-H_LINE_TO, 16,
-R_CUBIC_TO, -4.42f, 0, -8, -3.58f, -8, -8,
-V_LINE_TO, 26,
-R_CUBIC_TO, 0, -4.42f, 3.58f, -8, 8, -8,
-CLOSE,
-R_MOVE_TO, 0, 52,
-R_H_LINE_TO, 64,
-V_LINE_TO, 26,
-H_LINE_TO, 16,
-R_V_LINE_TO, 44,
-CLOSE,
-R_MOVE_TO, 37.46f, -17.39f,
-CUBIC_TO, 41.7f, 52.43f, 33.39f, 54.86f, 28, 61.33f,
-R_CUBIC_TO, 2.17f, -9.24f, 9.4f, -17.94f, 25.46f, -17.95f,
-V_LINE_TO, 33,
-LINE_TO, 68, 48,
-LINE_TO, 53.46f, 63,
-V_LINE_TO, 52.62f,
-CLOSE
diff --git a/ash/system/camera/camera_effects_controller.cc b/ash/system/camera/camera_effects_controller.cc
index b27d0b9..c92a7b2 100644
--- a/ash/system/camera/camera_effects_controller.cc
+++ b/ash/system/camera/camera_effects_controller.cc
@@ -17,11 +17,13 @@
 #include "ash/system/video_conference/video_conference_utils.h"
 #include "base/check_is_test.h"
 #include "base/check_op.h"
+#include "base/files/file_util.h"
 #include "base/functional/callback_helpers.h"
 #include "base/metrics/field_trial_params.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/notreached.h"
 #include "base/task/sequenced_task_runner.h"
+#include "base/task/thread_pool.h"
 #include "components/prefs/pref_change_registrar.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
@@ -40,6 +42,9 @@
 // - `bool` that's 'true' if background blur is enabled, false otherwise
 using CameraHalBackgroundBlurState = std::pair<cros::mojom::BlurLevel, bool>;
 
+// Directory that can be accessed by the camera module.
+constexpr char kImageDirForCameraModule[] = "/run/camera/";
+
 // Returns 'true' if `pref_value` is an allowable value of
 // `CameraEffectsController::BackgroundBlurPrefValue`, 'false' otherwise.
 bool IsValidBackgroundBlurPrefValue(int pref_value) {
@@ -137,10 +142,40 @@
   return CameraEffectsController::BackgroundBlurState::kOff;
 }
 
+// Copies image file from `camera_background_img_dir` to
+// `camera_background_run_dir`; Returns either the input `config` if the copy
+// succeeds or config with background-replace disabled if the copy fails.
+cros::mojom::EffectsConfigPtr CopyBackgroundImageFile(
+    cros::mojom::EffectsConfigPtr config,
+    const base::FilePath& camera_background_img_dir,
+    const base::FilePath& camera_background_run_dir) {
+  const base::FilePath background_image_filepath =
+      camera_background_img_dir.Append(config->background_filepath->value());
+  const base::FilePath background_run_filepath =
+      camera_background_run_dir.Append(config->background_filepath->value());
+
+  if (base::CreateDirectory(background_run_filepath.DirName()) &&
+      base::CopyFile(background_image_filepath, background_run_filepath)) {
+    base::File::Info file_info;
+    base::GetFileInfo(background_image_filepath, &file_info);
+    base::TouchFile(background_image_filepath, base::Time::Now(),
+                    file_info.last_modified);
+
+    return config;
+  } else {
+    // Return null if copy failed.
+    return cros::mojom::EffectsConfigPtr();
+  }
+}
+
 }  // namespace
 
 CameraEffectsController::CameraEffectsController()
-    : main_task_runner_(base::SequencedTaskRunner::GetCurrentDefault()) {
+    : camera_background_run_dir_(kImageDirForCameraModule),
+      main_task_runner_(base::SequencedTaskRunner::GetCurrentDefault()),
+      blocking_task_runner_(base::ThreadPool::CreateSequencedTaskRunner(
+          {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
+           base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})) {
   auto* session_controller = Shell::Get()->session_controller();
   DCHECK(session_controller);
   session_observation_.Observe(session_controller);
@@ -188,6 +223,18 @@
   registry->RegisterBooleanPref(prefs::kBackgroundReplace, false);
 
   registry->RegisterBooleanPref(prefs::kPortraitRelighting, false);
+
+  registry->RegisterFilePathPref(prefs::kBackgroundImagePath, base::FilePath());
+}
+
+void CameraEffectsController::SetBackgroundImage(
+    const base::FilePath& relative_path) {
+  cros::mojom::EffectsConfigPtr new_effects = current_effects_.Clone();
+  new_effects->replace_enabled = true;
+  new_effects->blur_enabled = false;
+  new_effects->background_filepath = relative_path;
+
+  SetCameraEffects(std::move(new_effects));
 }
 
 void CameraEffectsController::OnActiveUserPrefServiceChanged(
@@ -387,13 +434,17 @@
     config->light_intensity = intensity;
   }
 
-  // Directly calls the callback for testing case.
-  if (in_testing_mode_) {
-    CHECK_IS_TEST();
-    OnCameraEffectChanged(std::move(config));
+  if (config->replace_enabled) {
+    // Copy image file on the IO thread first.
+    blocking_task_runner_->PostTaskAndReplyWithResult(
+        FROM_HERE,
+        base::BindOnce(&CopyBackgroundImageFile, std::move(config),
+                       camera_background_img_dir_, camera_background_run_dir_),
+        base::BindOnce(
+            &CameraEffectsController::SetCameraEffectsInCameraHalDispatcherImpl,
+            weak_factory_.GetWeakPtr()));
   } else {
-    media::CameraHalDispatcherImpl::GetInstance()->SetCameraEffects(
-        std::move(config));
+    SetCameraEffectsInCameraHalDispatcherImpl(std::move(config));
   }
 }
 
@@ -420,6 +471,10 @@
 
   effects->replace_enabled =
       pref_change_registrar_->prefs()->GetBoolean(prefs::kBackgroundReplace);
+  if (effects->replace_enabled) {
+    effects->background_filepath = pref_change_registrar_->prefs()->GetFilePath(
+        prefs::kBackgroundImagePath);
+  }
   effects->relight_enabled =
       pref_change_registrar_->prefs()->GetBoolean(prefs::kPortraitRelighting);
   return effects;
@@ -442,6 +497,13 @@
   if (new_config->replace_enabled != current_effects_->replace_enabled) {
     pref_change_registrar_->prefs()->SetBoolean(prefs::kBackgroundReplace,
                                                 new_config->replace_enabled);
+    if (new_config->replace_enabled) {
+      pref_change_registrar_->prefs()->SetFilePath(
+          prefs::kBackgroundImagePath, new_config->background_filepath.value());
+    } else {
+      pref_change_registrar_->prefs()->SetFilePath(prefs::kBackgroundImagePath,
+                                                   base::FilePath());
+    }
   }
 
   if (new_config->relight_enabled != current_effects_->relight_enabled) {
@@ -555,4 +617,21 @@
       /*state=*/state_value));
 }
 
+void CameraEffectsController::SetCameraEffectsInCameraHalDispatcherImpl(
+    cros::mojom::EffectsConfigPtr config) {
+  // Skip if a null EffectsConfigPtr is passed in.
+  if (config.is_null()) {
+    return;
+  }
+
+  // Directly calls the callback for testing case.
+  if (in_testing_mode_) {
+    CHECK_IS_TEST();
+    OnCameraEffectChanged(std::move(config));
+  } else {
+    media::CameraHalDispatcherImpl::GetInstance()->SetCameraEffects(
+        std::move(config));
+  }
+}
+
 }  // namespace ash
diff --git a/ash/system/camera/camera_effects_controller.h b/ash/system/camera/camera_effects_controller.h
index c600bae..332c4ff 100644
--- a/ash/system/camera/camera_effects_controller.h
+++ b/ash/system/camera/camera_effects_controller.h
@@ -84,6 +84,9 @@
   // Called inside ash/ash_prefs.cc to register related prefs.
   static void RegisterProfilePrefs(PrefRegistrySimple* registry);
 
+  // Sets an image as the camera background.
+  void SetBackgroundImage(const base::FilePath& relative_path);
+
   // SessionObserver:
   void OnActiveUserPrefServiceChanged(PrefService* pref_service) override;
 
@@ -104,6 +107,16 @@
     in_testing_mode_ = in_testing_mode;
   }
 
+  void set_camera_background_img_dir_for_testing(
+      const base::FilePath& camera_background_img_dir) {
+    camera_background_img_dir_ = camera_background_img_dir;
+  }
+
+  void set_camera_background_run_dir_for_testing(
+      const base::FilePath& camera_background_run_dir) {
+    camera_background_run_dir_ = camera_background_run_dir;
+  }
+
  private:
   // AutozoomObserver:
   void OnAutozoomControlEnabledChanged(bool enabled) override;
@@ -132,10 +145,20 @@
                                       int state_value,
                                       int string_id);
 
+  // A helper for easier binding.
+  void SetCameraEffectsInCameraHalDispatcherImpl(
+      cros::mojom::EffectsConfigPtr config);
+
   // Used to bypass the CameraHalDispatcherImpl::SetCameraEffects for
   // testing purpose.
   bool in_testing_mode_ = false;
 
+  // Directory that stores the camera background images.
+  base::FilePath camera_background_img_dir_;
+
+  // Directory that stores the background images for the camera module to use.
+  base::FilePath camera_background_run_dir_;
+
   // Used for pref registration.
   std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
 
@@ -143,6 +166,10 @@
   // from the same thread.
   const scoped_refptr<base::SequencedTaskRunner> main_task_runner_;
 
+  // This task runner is used to copy background image file to
+  // `camera_background_run_dir_`.
+  const scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
+
   // Records current effects that is applied to camera hal server.
   cros::mojom::EffectsConfigPtr current_effects_;
 
diff --git a/ash/system/camera/camera_effects_controller_unittest.cc b/ash/system/camera/camera_effects_controller_unittest.cc
index 90049f4a..5f66bce14 100644
--- a/ash/system/camera/camera_effects_controller_unittest.cc
+++ b/ash/system/camera/camera_effects_controller_unittest.cc
@@ -21,6 +21,8 @@
 #include "ash/system/video_conference/video_conference_tray.h"
 #include "ash/test/ash_test_base.h"
 #include "base/command_line.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
 #include "base/memory/raw_ptr.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
@@ -49,6 +51,19 @@
 
     // Enable test mode to mock the SetCameraEffects calls.
     camera_effects_controller_->bypass_set_camera_effects_for_testing(true);
+
+    // Create fake camera_background_img_dir_ and camera_background_run_dir_.
+    ASSERT_TRUE(file_tmp_dir_.CreateUniqueTempDir());
+    camera_background_img_dir_ =
+        file_tmp_dir_.GetPath().AppendASCII("camera_background_img_dir_");
+    camera_background_run_dir_ =
+        file_tmp_dir_.GetPath().AppendASCII("camera_background_run_dir_");
+    ASSERT_TRUE(base::CreateDirectory(camera_background_img_dir_));
+    ASSERT_TRUE(base::CreateDirectory(camera_background_run_dir_));
+    camera_effects_controller_->set_camera_background_img_dir_for_testing(
+        camera_background_img_dir_);
+    camera_effects_controller_->set_camera_background_run_dir_for_testing(
+        camera_background_run_dir_);
   }
 
   void TearDown() override {
@@ -79,6 +94,15 @@
         ->GetInteger(prefs::kBackgroundBlur);
   }
 
+  // Returns a pair of <replace-enabled, background-image-filepath>.
+  std::pair<bool, std::string> GetBackgroundReplacePref() {
+    const auto* prefs =
+        Shell::Get()->session_controller()->GetActivePrefService();
+
+    return {prefs->GetBoolean(prefs::kBackgroundReplace),
+            prefs->GetFilePath(prefs::kBackgroundImagePath).value()};
+  }
+
   // Simulates toggling portrait relighting effect state. Note that the `state`
   // argument doesn't matter for toggle effects.
   void TogglePortraitRelightingEffectState() {
@@ -135,6 +159,10 @@
   FakeVideoConferenceTrayController* controller() { return controller_.get(); }
 
  protected:
+  base::ScopedTempDir file_tmp_dir_;
+  base::FilePath camera_background_img_dir_;
+  base::FilePath camera_background_run_dir_;
+
   raw_ptr<CameraEffectsController, DanglingUntriaged | ExperimentalAsh>
       camera_effects_controller_ = nullptr;
   std::unique_ptr<FakeVideoConferenceTrayController> controller_;
@@ -175,6 +203,18 @@
     EXPECT_FALSE(camera_effects_controller()->IsEffectControlAvailable(
         cros::mojom::CameraEffect::kBackgroundReplace));
   }
+
+  {
+    base::test::ScopedFeatureList scoped_feature_list;
+    scoped_feature_list.InitWithFeatures(
+        {features::kVideoConference, features::kVcBackgroundReplace}, {});
+    EXPECT_TRUE(camera_effects_controller()->IsEffectControlAvailable(
+        cros::mojom::CameraEffect::kBackgroundBlur));
+    EXPECT_TRUE(camera_effects_controller()->IsEffectControlAvailable(
+        cros::mojom::CameraEffect::kPortraitRelight));
+    EXPECT_TRUE(camera_effects_controller()->IsEffectControlAvailable(
+        cros::mojom::CameraEffect::kBackgroundReplace));
+  }
 }
 
 TEST_F(CameraEffectsControllerTest, BackgroundBlurOnEffectControlActivated) {
@@ -415,4 +455,60 @@
             cros::mojom::CameraAutoFramingState::OFF);
 }
 
+TEST_F(CameraEffectsControllerTest, SetBackgroundImageWithFileExists) {
+  SimulateUserLogin("testuser@gmail.com");
+
+  // Apply background blur first.
+  const auto state = CameraEffectsController::BackgroundBlurPrefValue::kLowest;
+  SetBackgroundBlurEffectState(state);
+  EXPECT_EQ(GetBackgroundBlurPref(), state);
+
+  // Create fake image file.
+  const std::string relative_path = "background/test.png";
+  base::FilePath file_fullpath =
+      camera_background_img_dir_.Append(relative_path);
+  ASSERT_TRUE(base::CreateDirectory(file_fullpath.DirName()));
+  ASSERT_TRUE(base::WriteFile(file_fullpath, ""));
+
+  // Set background image.
+  camera_effects_controller_->SetBackgroundImage(base::FilePath(relative_path));
+  base::RunLoop().RunUntilIdle();
+
+  // Check background replace result from pref.
+  EXPECT_THAT(GetBackgroundReplacePref(), testing::Pair(true, relative_path));
+
+  // Check the background blur is turned off.
+  EXPECT_EQ(GetBackgroundBlurPref(),
+            CameraEffectsController::BackgroundBlurPrefValue::kOff);
+
+  // Apply background blur again.
+  SetBackgroundBlurEffectState(state);
+  EXPECT_EQ(GetBackgroundBlurPref(), state);
+
+  // Background replace should be turned off.
+  EXPECT_THAT(GetBackgroundReplacePref(), testing::Pair(false, ""));
+}
+
+TEST_F(CameraEffectsControllerTest, SetBackgroundImageWithFileDoesNotExist) {
+  SimulateUserLogin("testuser@gmail.com");
+
+  // Apply background blur first.
+  const auto state = CameraEffectsController::BackgroundBlurPrefValue::kLowest;
+  SetBackgroundBlurEffectState(state);
+  EXPECT_EQ(GetBackgroundBlurPref(), state);
+
+  const std::string relative_path = "background/test.png";
+
+  // Set background image.
+  camera_effects_controller_->SetBackgroundImage(base::FilePath(relative_path));
+  base::RunLoop().RunUntilIdle();
+
+  // Because the image is not created, the above SetBackgroundImage should fail,
+  // so that the background replace pref should not be set.
+  EXPECT_THAT(GetBackgroundReplacePref(), testing::Pair(false, ""));
+
+  // Check the background blur is not changed.
+  EXPECT_EQ(GetBackgroundBlurPref(), state);
+}
+
 }  // namespace ash
diff --git a/ash/system/media/media_tray.cc b/ash/system/media/media_tray.cc
index 60df7038..65e92450 100644
--- a/ash/system/media/media_tray.cc
+++ b/ash/system/media/media_tray.cc
@@ -52,9 +52,9 @@
 constexpr int kNoMediaTextFontSizeIncrease = 2;
 constexpr int kNoMediaTextFontSize = 14;
 constexpr int kTitleFontSizeIncrease = 4;
-constexpr int kTitleViewHeight = 56;
+constexpr int kTitleViewHeight = 60;
 
-constexpr auto kTitleViewInsets = gfx::Insets::TLBR(0, 16, 0, 16);
+constexpr gfx::Insets kTitleViewInsets = gfx::Insets::VH(16, 16);
 
 // Minimum screen diagonal (in inches) for pinning global media controls
 // on shelf by default.
@@ -92,7 +92,6 @@
   GlobalMediaControlsTitleView() {
     auto* box_layout = SetLayoutManager(std::make_unique<views::BoxLayout>(
         views::BoxLayout::Orientation::kHorizontal, kTitleViewInsets));
-    box_layout->set_minimum_cross_axis_size(kTitleViewHeight);
     box_layout->set_cross_axis_alignment(
         views::BoxLayout::CrossAxisAlignment::kCenter);
 
@@ -106,12 +105,13 @@
       title_label_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
       TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosTitle1,
                                             *title_label_);
-
+      SetPreferredSize(gfx::Size(kRevampedTrayMenuWidth, kTitleViewHeight));
     } else {
       title_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
       title_label_->SetFontList(views::Label::GetDefaultFontList().Derive(
           kTitleFontSizeIncrease, gfx::Font::NORMAL,
           gfx::Font::Weight::MEDIUM));
+      SetPreferredSize(gfx::Size(kTrayMenuWidth, kTitleViewHeight));
     }
 
     // Media tray should always be pinned to shelf when we are opening the
@@ -390,6 +390,7 @@
       MediaNotificationProvider::Get()->GetMediaNotificationListView(
           kMenuSeparatorWidth, /*should_clip_height=*/true, item_id));
   if (base::FeatureList::IsEnabled(media::kGlobalMediaControlsCrOSUpdatedUI)) {
+    bubble_view->SetPreferredWidth(kRevampedTrayMenuWidth);
     content_view_->SetBorder(views::CreateEmptyBorder(
         gfx::Insets::TLBR(0, 0, kMediaNotificationListViewBottomPadding, 0)));
   }
diff --git a/ash/system/message_center/ash_notification_drag_controller.cc b/ash/system/message_center/ash_notification_drag_controller.cc
index 7254c67..60a2edc7 100644
--- a/ash/system/message_center/ash_notification_drag_controller.cc
+++ b/ash/system/message_center/ash_notification_drag_controller.cc
@@ -7,6 +7,7 @@
 #include "ash/root_window_controller.h"
 #include "ash/shell.h"
 #include "ash/system/message_center/ash_notification_view.h"
+#include "ash/system/message_center/message_center_utils.h"
 #include "ash/system/notification_center/notification_center_tray.h"
 #include "ash/system/status_area_widget.h"
 #include "ash/system/unified/unified_system_tray.h"
@@ -66,6 +67,12 @@
     const gfx::Point& press_pt,
     ui::OSExchangeData* data) {
   // Sets the image to show during drag.
+  // TODO(b/308814203): clean the static_cast checks by replacing
+  // `AshNotificationView*` with a base class.
+  if (!message_center_utils::IsAshNotificationView(sender)) {
+    return;
+  }
+
   AshNotificationView* notification_view =
       static_cast<AshNotificationView*>(sender);
   const absl::optional<gfx::ImageSkia> drag_image =
@@ -84,6 +91,12 @@
 int AshNotificationDragController::GetDragOperationsForView(
     views::View* sender,
     const gfx::Point& p) {
+  // TODO(b/308814203): clean the static_cast checks by replacing
+  // `AshNotificationView*` with a base class.
+  if (!message_center_utils::IsAshNotificationView(sender)) {
+    return ui::DragDropTypes::DRAG_NONE;
+  }
+
   const absl::optional<gfx::Rect> drag_area =
       static_cast<AshNotificationView*>(sender)->GetDragAreaBounds();
 
@@ -101,6 +114,12 @@
     views::View* sender,
     const gfx::Point& press_pt,
     const gfx::Point& p) {
+  // TODO(b/308814203): clean the static_cast checks by replacing
+  // `AshNotificationView*` with a base class.
+  if (!message_center_utils::IsAshNotificationView(sender)) {
+    return false;
+  }
+
   const AshNotificationView* const notification_view =
       static_cast<AshNotificationView*>(sender);
   const absl::optional<gfx::Rect> drag_area =
@@ -133,6 +152,11 @@
 
 void AshNotificationDragController::OnWillStartDragForView(
     views::View* dragged_view) {
+  // TODO(b/308814203): clean the static_cast checks by replacing
+  // `AshNotificationView*` with a base class.
+  if (!message_center_utils::IsAshNotificationView(dragged_view)) {
+    return;
+  }
   OnNotificationDragWillStart(static_cast<AshNotificationView*>(dragged_view));
 }
 
diff --git a/ash/system/message_center/ash_notification_view.cc b/ash/system/message_center/ash_notification_view.cc
index 7ff4ff2..a708cf66 100644
--- a/ash/system/message_center/ash_notification_view.cc
+++ b/ash/system/message_center/ash_notification_view.cc
@@ -1034,9 +1034,9 @@
         MessageViewFactory::Create(*notification, /*shown_in_popup=*/false);
     // The child can either be an AshNotificationView or an ARC custom
     // notification view.
-    if (notification->type() != message_center::NOTIFICATION_TYPE_CUSTOM ||
-        notification->notifier_id().type !=
-            message_center::NotifierType::ARC_APPLICATION) {
+    // TODO(b/308814203): clean the static_cast checks by replacing
+    // `AshNotificationView*` with a base class.
+    if (message_center_utils::IsAshNotification(notification)) {
       auto* ash_notification_view =
           static_cast<AshNotificationView*>(notification_view.get());
       ash_notification_view->SetGroupedChildExpanded(IsExpanded());
@@ -1229,16 +1229,9 @@
 
     int notification_count = 0;
     for (auto* child : grouped_notifications_container_->children()) {
-      auto* message_view = static_cast<message_center::MessageView*>(child);
-      std::string notification_id = message_view->notification_id();
-
-      message_center::Notification* notification =
-          message_center::MessageCenter::Get()->FindVisibleNotificationById(
-              notification_id);
-
-      if (notification->type() != message_center::NOTIFICATION_TYPE_CUSTOM ||
-          notification->notifier_id().type !=
-              message_center::NotifierType::ARC_APPLICATION) {
+      // TODO(b/308814203): clean the static_cast checks by replacing
+      // `AshNotificationView*` with a base class.
+      if (message_center_utils::IsAshNotificationView(child)) {
         auto* notification_view = static_cast<AshNotificationView*>(child);
         notification_view->AnimateGroupedChildExpandedCollapse(expanded);
         notification_view->SetGroupedChildExpanded(expanded);
diff --git a/ash/system/message_center/message_center_utils.cc b/ash/system/message_center/message_center_utils.cc
index 1a62b998..9b7b8fe 100644
--- a/ash/system/message_center/message_center_utils.cc
+++ b/ash/system/message_center/message_center_utils.cc
@@ -302,4 +302,25 @@
       gfx::ToFlooredSize(resized_size));
 }
 
+bool IsAshNotificationView(views::View* sender) {
+  auto* message_view = static_cast<message_center::MessageView*>(sender);
+  std::string notification_id = message_view->notification_id();
+
+  message_center::Notification* notification =
+      message_center::MessageCenter::Get()->FindVisibleNotificationById(
+          notification_id);
+
+  return IsAshNotification(notification);
+}
+
+bool IsAshNotification(const message_center::Notification* notification) {
+  if (!notification ||
+      (notification->type() == message_center::NOTIFICATION_TYPE_CUSTOM &&
+       notification->notifier_id().type ==
+           message_center::NotifierType::ARC_APPLICATION)) {
+    return false;
+  }
+  return true;
+}
+
 }  // namespace ash::message_center_utils
diff --git a/ash/system/message_center/message_center_utils.h b/ash/system/message_center/message_center_utils.h
index 54b56d3..ec1ec810 100644
--- a/ash/system/message_center/message_center_utils.h
+++ b/ash/system/message_center/message_center_utils.h
@@ -97,6 +97,16 @@
 ResizeImageIfExceedSizeLimit(const gfx::ImageSkia& input_image,
                              size_t size_limit_in_byte);
 
+// Check if the view can be casted to `AshNotificationView`.
+// TODO(b/308814203): remove this function after cleaning the static_cast
+// checks for casting `AshNotificationView*`.
+bool IsAshNotificationView(views::View* sender);
+
+// Check if the notification is Ash notification.
+// TODO(b/308814203): remove this function after cleaning the static_cast
+// checks for casting `AshNotificationView*`.
+bool IsAshNotification(const message_center::Notification* notification);
+
 }  // namespace ash::message_center_utils
 
 #endif  // ASH_SYSTEM_MESSAGE_CENTER_MESSAGE_CENTER_UTILS_H_
diff --git a/ash/system/message_center/notification_grouping_controller.cc b/ash/system/message_center/notification_grouping_controller.cc
index 1ef6b697..648d9858 100644
--- a/ash/system/message_center/notification_grouping_controller.cc
+++ b/ash/system/message_center/notification_grouping_controller.cc
@@ -368,12 +368,11 @@
       message_center->FindParentNotification(notification);
   std::string parent_id = parent_notification->id();
 
+  // TODO(b/308814203): clean the static_cast checks by replacing
+  // AshNotificationView* with a base class.
   auto* parent_view =
       (GetActiveNotificationViewController() &&
-       (parent_notification->type() !=
-            message_center::NOTIFICATION_TYPE_CUSTOM ||
-        parent_notification->notifier_id().type !=
-            message_center::NotifierType::ARC_APPLICATION))
+       message_center_utils::IsAshNotification(parent_notification))
           ? static_cast<AshNotificationView*>(
                 GetActiveNotificationViewController()
                     ->GetMessageViewForNotificationId(parent_id))
diff --git a/ash/system/notification_center/notification_center_tray.cc b/ash/system/notification_center/notification_center_tray.cc
index 12e9414..6e81dce7 100644
--- a/ash/system/notification_center/notification_center_tray.cc
+++ b/ash/system/notification_center/notification_center_tray.cc
@@ -118,7 +118,9 @@
   // `NotificationCenterTray` from the controller. We should make sure views are
   // only added by host views.
   notification_icons_controller_->AddNotificationTrayItems(tray_container());
-  if (features::IsPrivacyIndicatorsEnabled()) {
+
+  // Privacy indicator is only enabled when Video Conference is disabled.
+  if (!features::IsVideoConferenceEnabled()) {
     privacy_indicators_view_ = tray_container()->AddChildView(
         std::make_unique<PrivacyIndicatorsTrayItemView>(shelf()));
   }
@@ -218,7 +220,7 @@
 void NotificationCenterTray::UpdateLayout() {
   TrayBackgroundView::UpdateLayout();
 
-  if (features::IsPrivacyIndicatorsEnabled()) {
+  if (privacy_indicators_view_) {
     privacy_indicators_view_->UpdateAlignmentForShelf(shelf());
   }
 }
diff --git a/ash/system/notification_center/notification_center_tray_unittest.cc b/ash/system/notification_center/notification_center_tray_unittest.cc
index 4821887..6ca46f69 100644
--- a/ash/system/notification_center/notification_center_tray_unittest.cc
+++ b/ash/system/notification_center/notification_center_tray_unittest.cc
@@ -41,9 +41,6 @@
   ~NotificationCenterTrayTest() override = default;
 
   void SetUp() override {
-    scoped_feature_list_.InitWithFeatures(
-        {features::kCameraEffectsSupportedByHardware}, {});
-
     AshTestBase::SetUp();
 
     test_api_ = std::make_unique<NotificationCenterTestApi>();
@@ -52,8 +49,6 @@
   NotificationCenterTestApi* test_api() { return test_api_.get(); }
 
  private:
-  base::test::ScopedFeatureList scoped_feature_list_;
-
   std::unique_ptr<NotificationCenterTestApi> test_api_;
 };
 
@@ -298,25 +293,12 @@
   EXPECT_TRUE(test_api()->IsNotificationIconShown());
 }
 
-TEST_F(NotificationCenterTrayTest, NoPrivacyIndicators) {
-  // No privacy indicators when the feature is not enabled.
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitWithFeatures(
-      /*enabled_features=*/{},
-      /*disabled_features=*/{features::kVideoConference,
-                             features::kPrivacyIndicators});
-
-  auto notification_tray =
-      std::make_unique<NotificationCenterTray>(GetPrimaryShelf());
-  EXPECT_FALSE(notification_tray->privacy_indicators_view());
-}
-
 TEST_F(NotificationCenterTrayTest, NoPrivacyIndicatorsWhenVcEnabled) {
   // No privacy indicators when `kVideoConference` is enabled.
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitWithFeatures(
       /*enabled_features=*/{features::kVideoConference,
-                            features::kPrivacyIndicators},
+                            features::kCameraEffectsSupportedByHardware},
       /*disabled_features=*/{});
 
   auto notification_tray =
diff --git a/ash/system/notification_center/notification_list_view.cc b/ash/system/notification_center/notification_list_view.cc
index 1a3643f..ee4419d 100644
--- a/ash/system/notification_center/notification_list_view.cc
+++ b/ash/system/notification_center/notification_list_view.cc
@@ -691,13 +691,16 @@
   }
 
   // Update the child notification view with the updated notification.
-  auto* child_view = static_cast<AshNotificationView*>(
-      parent_view->FindGroupNotificationView(child_notification_id));
+  // TODO(b/308814203): clean the static_cast checks by replacing
+  // `AshNotificationView*` with a base class.
+  auto* child_view =
+      parent_view->FindGroupNotificationView(child_notification_id);
   auto* notification =
       MessageCenter::Get()->FindNotificationById(child_notification_id);
 
-  if (child_view && notification) {
-    child_view->UpdateWithNotification(*notification);
+  if (child_view && message_center_utils::IsAshNotification(notification)) {
+    auto* ash_child_view = static_cast<AshNotificationView*>(child_view);
+    ash_child_view->UpdateWithNotification(*notification);
     ResetBounds();
   }
 }
diff --git a/ash/system/privacy/privacy_indicators_controller.cc b/ash/system/privacy/privacy_indicators_controller.cc
index 2845f26..bbaffe1 100644
--- a/ash/system/privacy/privacy_indicators_controller.cc
+++ b/ash/system/privacy/privacy_indicators_controller.cc
@@ -106,7 +106,7 @@
     bool is_camera_used,
     bool is_microphone_used,
     scoped_refptr<PrivacyIndicatorsNotificationDelegate> delegate) {
-  if (!features::IsPrivacyIndicatorsEnabled()) {
+  if (features::IsVideoConferenceEnabled()) {
     return;
   }
 
@@ -135,9 +135,10 @@
                                  bool is_new_app,
                                  bool was_camera_in_use,
                                  bool was_microphone_in_use) {
-  if (!features::IsPrivacyIndicatorsEnabled()) {
+  if (features::IsVideoConferenceEnabled()) {
     return;
   }
+
   DCHECK(Shell::HasInstance());
   for (auto* root_window_controller :
        Shell::Get()->GetAllRootWindowControllers()) {
@@ -377,8 +378,9 @@
 }
 
 void UpdatePrivacyIndicatorsScreenShareStatus(bool is_screen_sharing) {
-  if (!features::IsPrivacyIndicatorsEnabled())
+  if (features::IsVideoConferenceEnabled()) {
     return;
+  }
 
   DCHECK(Shell::HasInstance());
   for (auto* root_window_controller :
diff --git a/ash/system/privacy/screen_security_controller.cc b/ash/system/privacy/screen_security_controller.cc
index 9ede481..b1ff596 100644
--- a/ash/system/privacy/screen_security_controller.cc
+++ b/ash/system/privacy/screen_security_controller.cc
@@ -31,8 +31,6 @@
 const char kScreenAccessNotificationId[] = "chrome://screen/access";
 const char kRemotingScreenShareNotificationId[] =
     "chrome://screen/remoting-share";
-const char kNotifierScreenAccess[] = "ash.screen-access";
-const char kNotifierRemotingScreenShare[] = "ash.remoting-screen-share";
 
 ScreenSecurityController::ScreenSecurityController() {
   Shell::Get()->AddShellObserver(this);
@@ -108,36 +106,22 @@
               },
               weak_ptr_factory_.GetWeakPtr(), is_screen_access_notification));
 
-  // If the feature is enabled, the notification should have the style of
-  // privacy indicators notification.
-  auto* notifier_id =
-      features::IsPrivacyIndicatorsEnabled()
-          ? kPrivacyIndicatorsNotifierId
-          : (is_screen_access_notification ? kNotifierScreenAccess
-                                           : kNotifierRemotingScreenShare);
-
   std::unique_ptr<Notification> notification = CreateSystemNotificationPtr(
       message_center::NOTIFICATION_TYPE_SIMPLE,
       is_screen_access_notification ? kScreenAccessNotificationId
                                     : kRemotingScreenShareNotificationId,
       l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SCREEN_SHARE_TITLE),
       message, std::u16string() /* display_source */, GURL(),
-      message_center::NotifierId(
-          message_center::NotifierType::SYSTEM_COMPONENT, notifier_id,
-          features::IsPrivacyIndicatorsEnabled()
-              ? NotificationCatalogName::kPrivacyIndicators
-              : NotificationCatalogName::kScreenSecurity),
+      message_center::NotifierId(message_center::NotifierType::SYSTEM_COMPONENT,
+                                 kPrivacyIndicatorsNotifierId,
+                                 NotificationCatalogName::kPrivacyIndicators),
       data, std::move(delegate),
-      features::IsPrivacyIndicatorsEnabled() ? kPrivacyIndicatorsScreenShareIcon
-                                             : kNotificationScreenshareIcon,
+      /*small_image=*/kPrivacyIndicatorsScreenShareIcon,
       message_center::SystemNotificationWarningLevel::NORMAL);
 
   notification->set_pinned(true);
-
-  if (features::IsPrivacyIndicatorsEnabled()) {
-    notification->set_accent_color_id(ui::kColorAshPrivacyIndicatorsBackground);
-    notification->set_parent_vector_small_image(kPrivacyIndicatorsIcon);
-  }
+  notification->set_accent_color_id(ui::kColorAshPrivacyIndicatorsBackground);
+  notification->set_parent_vector_small_image(kPrivacyIndicatorsIcon);
 
   message_center::MessageCenter::Get()->AddNotification(
       std::move(notification));
@@ -173,9 +157,7 @@
     return;
 
   CreateNotification(access_app_name, /*is_screen_access_notification=*/true);
-  if (features::IsPrivacyIndicatorsEnabled()) {
-    UpdatePrivacyIndicatorsScreenShareStatus(/*is_screen_sharing=*/true);
-  }
+  UpdatePrivacyIndicatorsScreenShareStatus(/*is_screen_sharing=*/true);
 }
 
 void ScreenSecurityController::OnScreenAccessStop() {
@@ -184,10 +166,7 @@
   }
 
   StopAllSessions(/*is_screen_access=*/true);
-
-  if (features::IsPrivacyIndicatorsEnabled()) {
-    UpdatePrivacyIndicatorsScreenShareStatus(/*is_screen_sharing=*/false);
-  }
+  UpdatePrivacyIndicatorsScreenShareStatus(/*is_screen_sharing=*/false);
 }
 
 void ScreenSecurityController::OnRemotingScreenShareStart(
@@ -203,9 +182,7 @@
   CreateNotification(
       l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SCREEN_SHARE_BEING_HELPED),
       /*is_screen_access_notification=*/false);
-
-  if (features::IsPrivacyIndicatorsEnabled())
-    UpdatePrivacyIndicatorsScreenShareStatus(/*is_screen_sharing=*/true);
+  UpdatePrivacyIndicatorsScreenShareStatus(/*is_screen_sharing=*/true);
 }
 
 void ScreenSecurityController::OnRemotingScreenShareStop() {
@@ -214,9 +191,7 @@
   }
 
   StopAllSessions(/*is_screen_access=*/false);
-
-  if (features::IsPrivacyIndicatorsEnabled())
-    UpdatePrivacyIndicatorsScreenShareStatus(/*is_screen_sharing=*/false);
+  UpdatePrivacyIndicatorsScreenShareStatus(/*is_screen_sharing=*/false);
 }
 
 void ScreenSecurityController::OnCastingSessionStartedOrStopped(bool started) {
diff --git a/ash/system/system_notification_controller.cc b/ash/system/system_notification_controller.cc
index 53bd567..bda67c6 100644
--- a/ash/system/system_notification_controller.cc
+++ b/ash/system/system_notification_controller.cc
@@ -58,7 +58,9 @@
   if (features::IsHotspotEnabled()) {
     hotspot_notifier_ = std::make_unique<ash::HotspotNotifier>();
   }
-  if (features::IsPrivacyIndicatorsEnabled()) {
+
+  // Privacy indicator is only enabled when Video Conference is disabled.
+  if (!features::IsVideoConferenceEnabled()) {
     privacy_indicators_controller_ =
         std::make_unique<PrivacyIndicatorsController>();
   }
diff --git a/ash/system/unified/unified_system_tray.cc b/ash/system/unified/unified_system_tray.cc
index 0b93c3bd..0c3adac 100644
--- a/ash/system/unified/unified_system_tray.cc
+++ b/ash/system/unified/unified_system_tray.cc
@@ -24,7 +24,6 @@
 #include "ash/system/model/system_tray_model.h"
 #include "ash/system/network/network_tray_view.h"
 #include "ash/system/power/tray_power.h"
-#include "ash/system/privacy/privacy_indicators_tray_item_view.h"
 #include "ash/system/privacy_screen/privacy_screen_toast_controller.h"
 #include "ash/system/status_area_widget.h"
 #include "ash/system/time/calendar_metrics.h"
@@ -167,13 +166,6 @@
             shelf, Shell::Get()->shell_delegate()->GetChannel()));
   }
 
-  // We do not show privacy indicators here in the new Quick Settings UI.
-  if (features::IsPrivacyIndicatorsEnabled() &&
-      !features::IsQsRevampEnabled()) {
-    privacy_indicators_view_ = AddTrayItemToContainer(
-        std::make_unique<PrivacyIndicatorsTrayItemView>(shelf));
-  }
-
   set_separator_visibility(false);
   set_use_bounce_in_animation(false);
 
@@ -560,15 +552,6 @@
     status.push_back(network_string);
   }
 
-  if (privacy_indicators_view_) {
-    status.push_back(
-        privacy_indicators_view_->GetVisible()
-            ? privacy_indicators_view_->GetTooltipText(gfx::Point())
-            : base::EmptyString16());
-  } else {
-    status.push_back(base::EmptyString16());
-  }
-
   status.push_back(managed_device_view_->GetVisible()
                        ? managed_device_view_->image_view()->GetTooltipText()
                        : base::EmptyString16());
@@ -604,9 +587,6 @@
 void UnifiedSystemTray::UpdateLayout() {
   TrayBackgroundView::UpdateLayout();
   time_view_->UpdateAlignmentForShelf(shelf());
-  if (privacy_indicators_view_) {
-    privacy_indicators_view_->UpdateAlignmentForShelf(shelf());
-  }
 }
 
 void UnifiedSystemTray::ShowBubbleInternal() {
diff --git a/ash/system/unified/unified_system_tray.h b/ash/system/unified/unified_system_tray.h
index d030abe..76a8817 100644
--- a/ash/system/unified/unified_system_tray.h
+++ b/ash/system/unified/unified_system_tray.h
@@ -40,7 +40,6 @@
 class ManagedDeviceTrayItemView;
 class NetworkTrayView;
 class NotificationIconsController;
-class PrivacyIndicatorsTrayItemView;
 class PrivacyScreenToastController;
 class Shelf;
 class TrayBubbleView;
@@ -237,10 +236,6 @@
   scoped_refptr<UnifiedSystemTrayModel> model() { return model_; }
   UnifiedSystemTrayBubble* bubble() { return bubble_.get(); }
 
-  PrivacyIndicatorsTrayItemView* privacy_indicators_view() {
-    return privacy_indicators_view_;
-  }
-
   ChannelIndicatorView* channel_indicator_view() {
     return channel_indicator_view_;
   }
@@ -304,8 +299,6 @@
   raw_ptr<CameraMicTrayItemView, ExperimentalAsh> camera_view_ = nullptr;
   raw_ptr<CameraMicTrayItemView, ExperimentalAsh> mic_view_ = nullptr;
   raw_ptr<TimeTrayItemView, ExperimentalAsh> time_view_ = nullptr;
-  raw_ptr<PrivacyIndicatorsTrayItemView, ExperimentalAsh>
-      privacy_indicators_view_ = nullptr;
   raw_ptr<HotspotTrayView, ExperimentalAsh> hotspot_tray_view_ = nullptr;
   raw_ptr<NetworkTrayView, ExperimentalAsh> network_tray_view_ = nullptr;
   raw_ptr<ChannelIndicatorView, ExperimentalAsh> channel_indicator_view_ =
diff --git a/ash/system/unified/unified_system_tray_unittest.cc b/ash/system/unified/unified_system_tray_unittest.cc
index d6055d4..d04f95f 100644
--- a/ash/system/unified/unified_system_tray_unittest.cc
+++ b/ash/system/unified/unified_system_tray_unittest.cc
@@ -18,8 +18,6 @@
 #include "ash/system/model/system_tray_model.h"
 #include "ash/system/notification_center/notification_center_tray.h"
 #include "ash/system/notification_center/notification_center_view.h"
-#include "ash/system/privacy/privacy_indicators_controller.h"
-#include "ash/system/privacy/privacy_indicators_tray_item_view.h"
 #include "ash/system/status_area_widget.h"
 #include "ash/system/status_area_widget_test_helper.h"
 #include "ash/system/time/time_tray_item_view.h"
@@ -916,30 +914,6 @@
   tray->CloseBubble();
 }
 
-TEST_P(UnifiedSystemTrayTest, NoPrivacyIndicators) {
-  // No privacy indicators when the feature is not enabled.
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitWithFeatures(
-      /*enabled_features=*/{},
-      /*disabled_features=*/{features::kVideoConference,
-                             features::kPrivacyIndicators});
-
-  auto tray = std::make_unique<UnifiedSystemTray>(GetPrimaryShelf());
-  EXPECT_FALSE(tray->privacy_indicators_view());
-}
-
-TEST_P(UnifiedSystemTrayTest, NoPrivacyIndicatorsWhenVcEnabled) {
-  // No privacy indicators when `kVideoConference` is enabled.
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitWithFeatures(
-      /*enabled_features=*/{features::kVideoConference,
-                            features::kPrivacyIndicators},
-      /*disabled_features=*/{});
-
-  auto tray = std::make_unique<UnifiedSystemTray>(GetPrimaryShelf());
-  EXPECT_FALSE(tray->privacy_indicators_view());
-}
-
 // Tests that there's no bubble in the kiosk mode.
 TEST_P(UnifiedSystemTrayTest, NoBubbleAndNoDetailedViewInKioskMode) {
   SimulateKioskMode(user_manager::USER_TYPE_KIOSK_APP);
@@ -961,74 +935,4 @@
   EXPECT_FALSE(IsBubbleShown());
 }
 
-// Test suite for the system tray when `kPrivacyIndicators` is enabled.
-class UnifiedSystemTrayPrivacyIndicatorsTest
-    : public AshTestBase,
-      public testing::WithParamInterface<bool> {
- public:
-  UnifiedSystemTrayPrivacyIndicatorsTest() = default;
-  UnifiedSystemTrayPrivacyIndicatorsTest(
-      const UnifiedSystemTrayPrivacyIndicatorsTest&) = delete;
-  UnifiedSystemTrayPrivacyIndicatorsTest& operator=(
-      const UnifiedSystemTrayPrivacyIndicatorsTest&) = delete;
-  ~UnifiedSystemTrayPrivacyIndicatorsTest() override = default;
-
-  void SetUp() override {
-    scoped_feature_list_.InitWithFeatureStates(
-        {{features::kPrivacyIndicators, true},
-         {features::kVideoConference, false},
-         {features::kQsRevamp, IsQsRevampEnabled()}});
-
-    AshTestBase::SetUp();
-  }
-
-  // TODO(b/305075031) clean up after the flag is removed.
-  bool IsQsRevampEnabled() { return true; }
-
- private:
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-INSTANTIATE_TEST_SUITE_P(All,
-                         UnifiedSystemTrayPrivacyIndicatorsTest,
-                         testing::Bool() /* IsQsRevampEnabled() */);
-
-// Tests that privacy indicators view is created and show/hide accordingly when
-// updated.
-TEST_P(UnifiedSystemTrayPrivacyIndicatorsTest, PrivacyIndicatorsVisibility) {
-  auto* system_tray =
-      StatusAreaWidgetTestHelper::GetStatusAreaWidget()->unified_system_tray();
-  auto* privacy_indicators_view = system_tray->privacy_indicators_view();
-
-  // No privacy indicators when `kQsRevamp` is enabled.
-  if (IsQsRevampEnabled()) {
-    EXPECT_FALSE(privacy_indicators_view);
-    return;
-  }
-
-  // Privacy indicators should be created and show/hide when updated.
-  EXPECT_TRUE(privacy_indicators_view);
-
-  EXPECT_FALSE(privacy_indicators_view->GetVisible());
-
-  scoped_refptr<PrivacyIndicatorsNotificationDelegate> delegate =
-      base::MakeRefCounted<PrivacyIndicatorsNotificationDelegate>();
-
-  // Updates the controller to simulate camera access, the privacy indicators
-  // should become visible.
-  PrivacyIndicatorsController::Get()->UpdatePrivacyIndicators(
-      /*app_id=*/"app_id", /*app_name=*/u"App Name",
-      /*is_camera_used=*/true,
-      /*is_microphone_used=*/false, delegate, PrivacyIndicatorsSource::kApps);
-  EXPECT_TRUE(privacy_indicators_view->GetVisible());
-
-  // Updates the controller to simulate that camera and microphone are not
-  // accessed, the privacy indicators should be hidden.
-  PrivacyIndicatorsController::Get()->UpdatePrivacyIndicators(
-      /*app_id=*/"app_id", /*app_name=*/u"App Name",
-      /*is_camera_used=*/false,
-      /*is_microphone_used=*/false, delegate, PrivacyIndicatorsSource::kApps);
-  EXPECT_FALSE(privacy_indicators_view->GetVisible());
-}
-
 }  // namespace ash
diff --git a/ash/wallpaper/wallpaper_controller_impl.cc b/ash/wallpaper/wallpaper_controller_impl.cc
index 7f061f9..2a31309d 100644
--- a/ash/wallpaper/wallpaper_controller_impl.cc
+++ b/ash/wallpaper/wallpaper_controller_impl.cc
@@ -2996,7 +2996,8 @@
 
 const ScheduledFeature& WallpaperControllerImpl::GetScheduleForOnlineWallpaper(
     const std::string& collection_id) const {
-  if (::ash::IsTimeOfDayWallpaper(collection_id)) {
+  if (::ash::IsTimeOfDayWallpaper(collection_id) &&
+      features::IsTimeOfDayWallpaperForcedAutoScheduleEnabled()) {
     return *time_of_day_scheduler_;
   } else {
     return *Shell::Get()->dark_light_mode_controller();
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc
index 872971a..e0624fdc 100644
--- a/ash/wallpaper/wallpaper_controller_unittest.cc
+++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -4783,6 +4783,10 @@
   if (!IsTimeOfDayEnabled()) {
     return;
   }
+
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitAndEnableFeature(
+      features::kTimeOfDayWallpaperForcedAutoSchedule);
   const auto backdrop_image_data = TimeOfDayImageSet();
   client_.AddCollection(wallpaper_constants::kTimeOfDayWallpaperCollectionId,
                         backdrop_image_data);
@@ -4852,6 +4856,46 @@
   EXPECT_TRUE(wallpaper_has_color(kSunsetImageColor));
 }
 
+// TODO(b/309020135): Remove this test after
+// `kTimeOfDayWallpaperForcedAutoSchedule` is launched.
+TEST_P(WallpaperControllerAutoScheduleTest,
+       DoesNotUpdateTimeOfDayWallpaperWithAutoColorModeOff) {
+  if (!IsTimeOfDayEnabled()) {
+    return;
+  }
+
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures(
+      {}, {features::kTimeOfDayWallpaperForcedAutoSchedule});
+  const auto backdrop_image_data = TimeOfDayImageSet();
+  client_.AddCollection(wallpaper_constants::kTimeOfDayWallpaperCollectionId,
+                        backdrop_image_data);
+
+  SimulateUserLogin(kAccountId1);
+  Shell::Get()->dark_light_mode_controller()->SetAutoScheduleEnabled(false);
+
+  OnlineWallpaperParams params(
+      kAccountId1, wallpaper_constants::kTimeOfDayWallpaperCollectionId,
+      WALLPAPER_LAYOUT_CENTER_CROPPED,
+      /*preview_mode=*/false, /*from_user=*/true,
+      /*daily_refresh_enabled=*/false,
+      wallpaper_constants::kDefaultTimeOfDayWallpaperUnitId, /*variants=*/{});
+  for (const backdrop::Image& backdrop_image : backdrop_image_data) {
+    params.variants.emplace_back(backdrop_image.asset_id(),
+                                 GURL(backdrop_image.image_url()),
+                                 backdrop_image.image_type());
+  }
+
+  base::test::TestFuture<bool> future;
+  controller_->SetOnlineWallpaper(params, future.GetCallback());
+  ASSERT_TRUE(future.Get());
+
+  TestWallpaperControllerObserver observer(controller_);
+  // 7 P.M.
+  task_environment()->FastForwardBy(base::Hours(17));
+  EXPECT_EQ(observer.wallpaper_changed_count(), 0);
+}
+
 TEST_P(WallpaperControllerTest,
        UpdateWallpaperOnScheduleCheckpointChanged_WithReplacedAsset) {
   SimulateUserLogin(kAccountId1);
diff --git a/ash/webui/camera_app_ui/resources/js/mojo/device_operator.ts b/ash/webui/camera_app_ui/resources/js/mojo/device_operator.ts
index 9476354..3876dea 100644
--- a/ash/webui/camera_app_ui/resources/js/mojo/device_operator.ts
+++ b/ash/webui/camera_app_ui/resources/js/mojo/device_operator.ts
@@ -39,6 +39,7 @@
   GetCameraAppDeviceStatus,
   MojoBlob,
   PointF,
+  PortraitModeSegResult,
   ResultMetadataObserverCallbackRouter,
   StillCaptureResultObserverCallbackRouter,
   StreamType,
@@ -615,11 +616,6 @@
    *     operation is not supported.
    */
   async takePortraitModePhoto(deviceId: string): Promise<Array<Promise<Blob>>> {
-    // TODO(b/244503017): Add definitions for the portrait mode segmentation
-    // result in the mojom file.
-    const PORTRAIT_SUCCESS = 0;
-    const PORTRAIT_NO_FACES = 3;
-
     const normalCapture = new CancelableEvent<Blob>();
     const portraitCapture = new CancelableEvent<Blob>();
     const portraitEvents = new Map([
@@ -637,11 +633,12 @@
             event.signalError(new Error(`Capture failed.`));
             return;
           }
-          if (effect === Effect.PORTRAIT_MODE && status !== PORTRAIT_SUCCESS) {
+          if (effect === Effect.PORTRAIT_MODE &&
+              status !== PortraitModeSegResult.kSuccess) {
             // We only appends the blob result to the output when the status
-            // code is `PORTRAIT_SUCCESS`. For any other status code, the blob
+            // code is `kSuccess`. For any other status code, the blob
             // will be the original photo and will not be shown to the user.
-            if (status === PORTRAIT_NO_FACES) {
+            if (status === PortraitModeSegResult.kNoFaces) {
               event.signalError(new PortraitErrorNoFaceDetected());
               return;
             }
diff --git a/ash/webui/camera_app_ui/resources/js/mojo/type.ts b/ash/webui/camera_app_ui/resources/js/mojo/type.ts
index 11f0bb2..3e4fe9b 100644
--- a/ash/webui/camera_app_ui/resources/js/mojo/type.ts
+++ b/ash/webui/camera_app_ui/resources/js/mojo/type.ts
@@ -57,6 +57,10 @@
 export type{CameraInfo} from
     '../../mojom/media/capture/video/chromeos/mojom/camera_common.mojom-webui.js';
 export {
+  PortraitModeSegResult,
+} from
+    '../../mojom/media/capture/video/chromeos/mojom/camera_features.mojom-webui.js';
+export {
   EntryType,
 } from
     '../../mojom/media/capture/video/chromeos/mojom/camera_metadata.mojom-webui.js';
diff --git a/ash/webui/camera_app_ui/resources/js/views/camera.ts b/ash/webui/camera_app_ui/resources/js/views/camera.ts
index bdf1a458..ddb3e15 100644
--- a/ash/webui/camera_app_ui/resources/js/views/camera.ts
+++ b/ash/webui/camera_app_ui/resources/js/views/camera.ts
@@ -605,38 +605,46 @@
       pendingPortrait: Promise<PhotoResult>): Promise<void> {
     state.set(PerfEvent.PORTRAIT_MODE_CAPTURE_POST_PROCESSING, true);
 
-    pendingReference = this.cropIfUsingSquareResolution(pendingReference);
-    pendingPortrait = this.cropIfUsingSquareResolution(pendingPortrait);
+    let filenamer: Filenamer;
 
-    let hasError = false;
-    try {
-      const {timestamp, resolution, blob, metadata} =
-          await this.checkPhotoResult(pendingReference);
-
-      metrics.sendCaptureEvent({
-        facing: this.getFacing(),
-        resolution,
-        shutterType: this.shutterType,
-        isVideoSnapshot: false,
-        resolutionLevel: this.cameraManager.getPhotoResolutionLevel(resolution),
-        aspectRatioSet: this.cameraManager.getAspectRatioSet(resolution),
-      });
-
-      // Save reference.
-      const filenamer = new Filenamer(timestamp);
-      const name = filenamer.newBurstName(false);
+    const saveReference = async () => {
+      const pendingCroppedReference =
+          this.cropIfUsingSquareResolution(pendingReference);
       try {
+        const {timestamp, resolution, blob, metadata} =
+            await this.checkPhotoResult(pendingCroppedReference);
+
+        metrics.sendCaptureEvent({
+          facing: this.getFacing(),
+          resolution,
+          shutterType: this.shutterType,
+          isVideoSnapshot: false,
+          resolutionLevel:
+              this.cameraManager.getPhotoResolutionLevel(resolution),
+          aspectRatioSet: this.cameraManager.getAspectRatioSet(resolution),
+        });
+
+        filenamer = filenamer ?? new Filenamer(timestamp);
+        const name = filenamer.newBurstName(false);
         await this.resultSaver.savePhoto(
             blob, ToteMetricFormat.PHOTO, name, metadata);
       } catch (e) {
         toast.show(I18nString.ERROR_MSG_SAVE_FILE_FAILED);
         throw e;
       }
+    };
 
+    const savePortrait = async () => {
+      const pendingCroppedPortrait =
+          this.cropIfUsingSquareResolution(pendingPortrait);
       try {
-        // Save portrait.
-        const {blob: portraitBlob, metadata: portraitMetadata} =
-            await pendingPortrait;
+        const {
+          timestamp: portraitTimestamp,
+          blob: portraitBlob,
+          metadata: portraitMetadata,
+        } = await pendingCroppedPortrait;
+
+        filenamer = filenamer ?? new Filenamer(portraitTimestamp);
         const name = filenamer.newBurstName(true);
         await this.resultSaver.savePhoto(
             portraitBlob, ToteMetricFormat.PHOTO, name, portraitMetadata);
@@ -647,13 +655,22 @@
           throw e;
         }
       }
-    } catch (e) {
-      hasError = true;
-      throw e;
-    } finally {
-      state.set(
-          PerfEvent.PORTRAIT_MODE_CAPTURE_POST_PROCESSING, false,
-          {hasError, facing: this.getFacing()});
+    };
+
+    let error = null;
+    const results = await Promise.allSettled([saveReference(), savePortrait()]);
+    for (const result of results) {
+      if (result.status === 'rejected') {
+        error = result.reason;
+        break;
+      }
+    }
+    const hasError = error !== null;
+    state.set(
+        PerfEvent.PORTRAIT_MODE_CAPTURE_POST_PROCESSING, false,
+        {hasError, facing: this.getFacing()});
+    if (hasError) {
+      throw error;
     }
     ChromeHelper.getInstance().maybeTriggerSurvey();
   }
diff --git a/ash/webui/common/resources/smb_shares/add_smb_share_dialog.html b/ash/webui/common/resources/smb_shares/add_smb_share_dialog.html
index 2f24361..956d4b7 100644
--- a/ash/webui/common/resources/smb_shares/add_smb_share_dialog.html
+++ b/ash/webui/common/resources/smb_shares/add_smb_share_dialog.html
@@ -1,22 +1,9 @@
     <style include="cr-shared-style md-select">
-      :host-context([theme='legacy']) cr-dialog::part(wrapper) {
-        /* Subtract the internal padding in <cr-dialog>. */
-        padding: calc(24px - 20px);
-      }
-
-      :host-context([theme='legacy']) cr-dialog::part(dialog) {
-        background-color: var(--cros-bg-color-elevation-3);
-      }
-
-      :host-context([theme='refresh23']) cr-dialog::part(dialog) {
+      cr-dialog::part(dialog) {
         background-color: var(--cros-sys-dialog_container);
       }
 
-      :host-context([theme='legacy']) [slot=title] {
-        --cr-primary-text-color: var(--cros-text-color-primary);
-      }
-
-      :host-context([theme='refresh23']) [slot=title] {
+      [slot=title] {
         --cr-dialog-title-slot-padding-bottom: 32px;
         --cr-dialog-title-slot-padding-end: 32px;
         --cr-dialog-title-slot-padding-start: 32px;
@@ -25,30 +12,18 @@
         font: var(--cros-display-7-font);
       }
 
-      :host-context([theme='legacy']) [slot='button-container']  {
-        padding-bottom: 20px;
-        padding-top: 32px;
-      }
-
-      :host-context([theme='refresh23']) [slot='button-container'] {
+      [slot='button-container'] {
         --cr-dialog-button-container-padding-bottom: 28px;
         --cr-dialog-button-container-padding-horizontal: 32px;
         padding-top: 0;
       }
 
-      :host-context([theme='refresh23']) #dialog [slot=body] {
+      #dialog [slot=body] {
         --cr-dialog-body-padding-horizontal: 32px;
         --cr-form-field-bottom-spacing: 8px;
       }
 
-      :host-context([theme='legacy']) .md-select {
-        --md-select-bg-color: var(--cros-textfield-background-color);
-        --md-select-focus-shadow-color: var(--cros-focus-ring-color);
-        --md-select-text-color: var(--cros-text-color-primary);
-        width: 100%;
-      }
-
-      :host-context([theme='refresh23']) .md-select {
+      .md-select {
         --md-select-bg-color: var(--cros-sys-input_field_on_base);
         --md-select-focus-shadow-color: var(--cros-sys-focus_ring);
         --md-select-text-color: var(--cros-sys-on_surface);
@@ -58,28 +33,7 @@
         width: 100%;
       }
 
-      :host-context([theme='legacy']) cr-searchable-drop-down {
-        --cr-searchable-drop-down-bg-color: var(--cros-bg-color-elevation-2);
-        --cr-searchable-drop-down-icon-color-focus:
-            var(--cros-textfield-label-color);
-        --cr-searchable-drop-down-list-item-color:
-            var(--cros-text-color-primary);
-        --cr-searchable-drop-down-list-bg-color-selected:
-            var(--cros-ripple-color);
-        --cr-searchable-drop-down-list-bg-color-active:
-            var(--cros-ripple-color);
-        --cr-searchable-drop-down-shadow: var(--cros-elevation-2-shadow);
-        --cr-searchable-drop-down-spinner-color:
-            var(--cros-icon-color-prominent);
-        /* cr_searchable_drop_down will hard code its width without this
-          variable. */
-        --cr-searchable-drop-down-width: auto;
-        --cr-secondary-text-color: var(--cros-text-color-secondary);
-        --iron-icon-fill-color: var(--cros-textfield-label-color);
-        display: block;
-      }
-
-      :host-context([theme='refresh23']) cr-searchable-drop-down {
+      cr-searchable-drop-down {
         --cr-searchable-drop-down-bg-color: var(--cros-sys-base_elevated);
         --cr-searchable-drop-down-icon-color-focus:
             var(--cros-sys-on_surface);
@@ -97,17 +51,8 @@
         display: block;
       }
 
-      :host-context([theme='legacy']) cr-input,
-      :host-context([theme='legacy']) cr-searchable-drop-down::part(input) {
-        --cr-form-field-label-color: var(--cros-textfield-label-color);
-        --cr-input-background-color: var(--cros-textfield-background-color);
-        --cr-input-color: var(--cros-textfield-input-color);
-        --cr-input-error-color: var(--cros-textfield-label-color-error);
-        --cr-input-focus-color: var(--cros-textfield-label-color-focus);
-      }
-
-      :host-context([theme='refresh23']) cr-input,
-      :host-context([theme='refresh23']) cr-searchable-drop-down::part(input) {
+      cr-input,
+      cr-searchable-drop-down::part(input) {
         --cr-form-field-label-color: var(--cros-sys-on_surface);
         --cr-input-background-color: var(--cros-sys-input_field_on_base);
         --cr-input-border-radius: 8px;
@@ -127,17 +72,7 @@
         margin-bottom: var(--cr-form-field-bottom-spacing);
       }
 
-      :host-context([theme='legacy']) #saveCredentialsCheckbox {
-        --cr-checkbox-checked-box-color: var(--cros-icon-color-prominent);
-        --cr-checkbox-label-color: var(--cros-textfield-label-color);
-        --cr-checkbox-mark-color: var(--cros-bg-color);
-        --cr-checkbox-ripple-checked-color: var(--cros-focus-aura-color);
-        --cr-checkbox-ripple-opacity: 1;
-        --cr-checkbox-ripple-unchecked-color: var(--cros-ripple-color);
-        --cr-checkbox-unchecked-box-color: var(--cros-icon-color-primary);
-      }
-
-      :host-context([theme='refresh23']) #saveCredentialsCheckbox {
+      #saveCredentialsCheckbox {
         --cr-checkbox-checked-box-color: var(--cros-sys-primary);
         --cr-checkbox-label-color: var(--cros-sys-on_surface);
         --cr-checkbox-mark-color: var(--cros-sys-on_primary);
@@ -147,12 +82,7 @@
         --cr-checkbox-unchecked-box-color: var(--cros-sys-on_surface);
       }
 
-      :host-context([theme='legacy']):host-context(.focus-outline-visible)
-          #saveCredentialsCheckbox:focus-within {
-        --cr-checkbox-ripple-ring: 2px solid var(--cros-focus-ring-color);
-      }
-
-      :host-context([theme='refresh23']):host-context(.focus-outline-visible)
+      :host-context(.focus-outline-visible)
           #saveCredentialsCheckbox:focus-within {
         --cr-checkbox-ripple-ring: 2px solid var(--cros-sys-focus_ring);
       }
@@ -161,36 +91,7 @@
         --cros-checkbox-reserve-inline-start: 0px;
       }
 
-      :host-context([theme='legacy']) cr-button {
-        --active-bg: transparent;
-        --active-shadow:
-            0 1px 2px var(--cros-button-active-shadow-color-key-secondary),
-            0 1px 3px var(--cros-button-active-shadow-color-ambient-secondary);
-        --active-shadow-action:
-            0 1px 2px var(--cros-button-active-shadow-color-key-primary),
-            0 1px 3px var(--cros-button-active-shadow-color-ambient-primary);
-        --bg-action: var(--cros-button-background-color-primary);
-        --border-color: var(--cros-button-stroke-color-secondary);
-        --disabled-bg-action:
-            var(--cros-button-background-color-primary-disabled);
-        --disabled-bg: var(--cros-button-background-color-primary-disabled);
-        --disabled-border-color:
-            var(--cros-button-stroke-color-secondary-disabled);
-        --disabled-text-color:
-            var(--cros-button-label-color-secondary-disabled);
-        --hover-bg-action:
-            var(--cros-button-background-color-primary-hover-preblended);
-        --hover-bg-color: var(--cros-button-background-color-secondary-hover);
-        --hover-border-color: var(--cros-button-stroke-color-secondary-hover);
-        --ink-color: var(--cros-button-ripple-color-secondary);
-        --ripple-opacity-action: var(--cros-button-primary-ripple-opacity);
-        --ripple-opacity: var(--cros-button-secondary-ripple-opacity);
-        --text-color-action: var(--cros-button-label-color-primary);
-        --text-color: var(--cros-button-label-color-secondary);
-        position: relative;
-      }
-
-      :host-context([theme='refresh23']) cr-button {
+      cr-button {
         --active-bg: transparent;
         --active-shadow: none;
         --active-shadow-action: none;
@@ -215,36 +116,21 @@
         position: relative;
       }
 
-      :host-context([theme='refresh23']) cr-button.cancel-button {
+      cr-button.cancel-button {
         background-color: var(--cros-sys-primary_container);
       }
 
-      :host-context([theme='refresh23'])
-          cr-button.cancel-button:hover::part(hoverBackground) {
+      cr-button.cancel-button:hover::part(hoverBackground) {
         background-color: var(--cros-sys-hover_on_subtle);
         display: block;
       }
 
-      :host-context([theme='refresh23'])
-          cr-button.action-button:hover::part(hoverBackground) {
+      cr-button.action-button:hover::part(hoverBackground) {
         background-color: var(--cros-sys-hover_on_prominent);
         display: block;
       }
 
-      :host-context([theme='legacy']) cr-button.action-button {
-        --ink-color: var(--cros-button-ripple-color-primary);
-      }
-
-      :host-context([theme='legacy']):host-context(.focus-outline-visible)
-          cr-button:focus {
-        /* disable the focus shadow because we use outline below */
-        box-shadow: none;
-        outline: 2px solid var(--cros-focus-ring-color);
-        outline-offset: 2px;
-      }
-
-      :host-context([theme='refresh23']):host-context(.focus-outline-visible)
-          cr-button:focus {
+      :host-context(.focus-outline-visible) cr-button:focus {
         /* disable the focus shadow because we use outline below */
         box-shadow: none;
         outline: 2px solid var(--cros-sys-focus_ring);
@@ -264,21 +150,11 @@
         height: 32px;
       }
 
-      :host-context([theme='legacy']) #general-error-icon {
-        --iron-icon-fill-color: var(--cros-icon-color-alert);
-      }
-
-      :host-context([theme='refresh23']) #general-error-icon {
+      #general-error-icon {
         --iron-icon-fill-color: var(--cros-sys-error);
       }
 
-      :host-context([theme='legacy']) #general-error-message {
-        color: var(--cros-text-color-alert);
-        display: inline-block;
-        font-size: 10px;
-      }
-
-      :host-context([theme='refresh23']) #general-error-message {
+      #general-error-message {
         color: var(--cros-sys-error);
         display: inline-block;
         font-size: 10px;
diff --git a/ash/webui/common/resources/smb_shares/add_smb_share_dialog.js b/ash/webui/common/resources/smb_shares/add_smb_share_dialog.js
index 1d7f4381..ab9d5712 100644
--- a/ash/webui/common/resources/smb_shares/add_smb_share_dialog.js
+++ b/ash/webui/common/resources/smb_shares/add_smb_share_dialog.js
@@ -170,9 +170,6 @@
   /** @override */
   created() {
     this.browserProxy_ = SmbBrowserProxyImpl.getInstance();
-
-    const theme = this.isJellyEnabled_() ? 'refresh23' : 'legacy';
-    document.documentElement.setAttribute('theme', theme);
   },
 
   /** @override */
diff --git a/ash/wm/desks/desk_bar_view.cc b/ash/wm/desks/desk_bar_view.cc
index e9575fc..e990ee4 100644
--- a/ash/wm/desks/desk_bar_view.cc
+++ b/ash/wm/desks/desk_bar_view.cc
@@ -22,26 +22,15 @@
     : DeskBarViewBase(root, DeskBarViewBase::Type::kDeskButton) {}
 
 gfx::Size DeskBarView::CalculatePreferredSize() const {
-  // For desk button bar, it comes with dynamic width. Thus, we calculate
-  // the preferred width (summation of all child elements and paddings) and
-  // use the full available width as the upper limit.
-  // TODO(b/301663756): consolidate size calculation for the desk bar and its
-  // scroll contents.
-  int width = 0;
-  for (auto* child : scroll_view_contents_->children()) {
-    if (!child->GetVisible()) {
-      continue;
-    }
-    if (width) {
-      width += kDeskBarMiniViewsSpacing;
-    }
-    width += child->GetPreferredSize().width();
-  }
-  width += kDeskBarScrollViewMinimumHorizontalPaddingDeskButton * 2 +
-           kDeskBarDeskPreviewViewFocusRingThicknessAndPadding * 2;
-  width = std::min(width, GetAvailableBounds().width());
-
-  return {width, GetPreferredBarHeight(root_, type_, state_)};
+  // The preferred size should be its scroll view contents' size plus the
+  // horizontal padding at both left/right. In addition, it should not exceed
+  // the available size.
+  gfx::Size preferred_size = scroll_view_contents_->GetPreferredSize();
+  preferred_size.Enlarge(
+      /*grow_width=*/kDeskBarScrollViewMinimumHorizontalPaddingDeskButton * 2,
+      /*grow_height=*/0);
+  preferred_size.SetToMin(GetAvailableBounds().size());
+  return preferred_size;
 }
 
 gfx::Rect DeskBarView::GetAvailableBounds() const {
diff --git a/ash/wm/desks/desk_bar_view_base.cc b/ash/wm/desks/desk_bar_view_base.cc
index 10b09490..19b88e1 100644
--- a/ash/wm/desks/desk_bar_view_base.cc
+++ b/ash/wm/desks/desk_bar_view_base.cc
@@ -4,6 +4,8 @@
 
 #include "ash/wm/desks/desk_bar_view_base.h"
 
+#include <vector>
+
 #include "ash/keyboard/ui/keyboard_ui_controller.h"
 #include "ash/public/cpp/saved_desk_delegate.h"
 #include "ash/public/cpp/shelf_types.h"
@@ -141,7 +143,7 @@
   DeskBarScrollViewLayout& operator=(const DeskBarScrollViewLayout&) = delete;
   ~DeskBarScrollViewLayout() override = default;
 
-  int GetContentViewX(int content_width) const {
+  int GetContentViewX(int contents_width) const {
     // The x of the first mini view should include the focus ring thickness and
     // padding into consideration, otherwise the focus ring won't be drawn on
     // the left side of the first mini view. `bar_view` is centralized in
@@ -151,7 +153,7 @@
     if (bar_view_->type() == DeskBarViewBase::Type::kOverview ||
         shelf_type == ShelfAlignment::kBottom ||
         shelf_type == ShelfAlignment::kBottomLocked) {
-      return (width_ - content_width) / 2 +
+      return (width_ - contents_width) / 2 +
              kDeskBarDeskPreviewViewFocusRingThicknessAndPadding;
     }
 
@@ -160,7 +162,7 @@
     }
 
     CHECK_EQ(shelf_type, ShelfAlignment::kRight);
-    return width_ - content_width +
+    return width_ - contents_width +
            kDeskBarDeskPreviewViewFocusRingThicknessAndPadding;
   }
 
@@ -188,45 +190,37 @@
   void LayoutInternal(views::View* host) {
     const gfx::Rect scroll_bounds = bar_view_->scroll_view_->bounds();
 
+    UpdateChildViewsVisibility();
+
+    const gfx::Size contents_size = host->GetPreferredSize();
+
     // `host` here is `scroll_view_contents_`.
     if (bar_view_->IsZeroState()) {
       host->SetBoundsRect(scroll_bounds);
+
       auto* zero_state_default_desk_button =
           bar_view_->zero_state_default_desk_button();
       const gfx::Size zero_state_default_desk_button_size =
           zero_state_default_desk_button->GetPreferredSize();
-
       auto* zero_state_new_desk_button =
           bar_view_->zero_state_new_desk_button();
       const gfx::Size zero_state_new_desk_button_size =
           zero_state_new_desk_button->GetPreferredSize();
-
       auto* zero_state_library_button = bar_view_->zero_state_library_button();
       const gfx::Size zero_state_library_button_size =
           bar_view_->ShouldShowLibraryUi()
               ? zero_state_library_button->GetPreferredSize()
               : gfx::Size();
-      const int width_for_zero_state_library_button =
-          bar_view_->ShouldShowLibraryUi()
-              ? zero_state_library_button_size.width() +
-                    kDeskBarZeroStateButtonSpacing
-              : 0;
 
-      const int content_width = zero_state_default_desk_button_size.width() +
-                                kDeskBarZeroStateButtonSpacing +
-                                zero_state_new_desk_button_size.width() +
-                                width_for_zero_state_library_button;
-      zero_state_default_desk_button->SetBoundsRect(
-          gfx::Rect(gfx::Point((scroll_bounds.width() - content_width) / 2,
-                               kDeskBarZeroStateY),
-                    zero_state_default_desk_button_size));
+      zero_state_default_desk_button->SetBoundsRect(gfx::Rect(
+          gfx::Point((scroll_bounds.width() - contents_size.width()) / 2,
+                     kDeskBarZeroStateY),
+          zero_state_default_desk_button_size));
       // Update this button's text since it may changes while removing a desk
       // and going back to the zero state.
       zero_state_default_desk_button->UpdateLabelText();
       // Make sure these two buttons are always visible while in zero state bar
       // since they are invisible in expanded state bar.
-      zero_state_default_desk_button->SetVisible(true);
-      zero_state_new_desk_button->SetVisible(true);
       zero_state_new_desk_button->SetBoundsRect(gfx::Rect(
           gfx::Point(zero_state_default_desk_button->bounds().right() +
                          kDeskBarZeroStateButtonSpacing,
@@ -239,7 +233,6 @@
                                      kDeskBarZeroStateButtonSpacing,
                                  kDeskBarZeroStateY),
                       zero_state_library_button_size));
-        zero_state_library_button->SetVisible(bar_view_->ShouldShowLibraryUi());
       }
       return;
     }
@@ -255,41 +248,21 @@
       base::ranges::reverse(mini_views);
     }
 
-    auto* expanded_state_library_button =
-        bar_view_->expanded_state_library_button();
-    const bool expanded_state_library_button_visible =
-        expanded_state_library_button &&
-        expanded_state_library_button->GetVisible();
-
-    gfx::Size mini_view_size = mini_views[0]->GetPreferredSize();
-
-    // The new desk button and library button in the expanded bar view has the
-    // same size as mini view.
-    const int num_items = static_cast<int>(mini_views.size()) +
-                          (expanded_state_library_button_visible ? 2 : 1);
-
-    // Content width is sum of the width of all views, and plus the spacing
-    // between the views, the focus ring's thickness and padding on each sides.
-    // TODO(b/301663756): consolidate size calculation for the desk bar and its
-    // scroll contents.
-    const int content_width =
-        num_items * (mini_view_size.width() + kDeskBarMiniViewsSpacing) -
-        kDeskBarMiniViewsSpacing +
-        kDeskBarDeskPreviewViewFocusRingThicknessAndPadding * 2;
-    width_ = std::max(scroll_bounds.width(), content_width);
+    width_ = std::max(scroll_bounds.width(), contents_size.width());
 
     // Update the size of the `host`, which is `scroll_view_contents_` here.
     // This is done to make sure its size can be updated on mini views' adding
     // or removing, then `scroll_view_` will know whether the contents need to
     // be scolled or not.
-    host->SetSize(gfx::Size(width_, scroll_bounds.height()));
+    host->SetSize(gfx::Size(width_, contents_size.height()));
 
     // The x of the first mini view should include the focus ring thickness and
     // padding into consideration, otherwise the focus ring won't be drawn on
     // the left side of the first mini view.
-    int x = GetContentViewX(content_width);
+    int x = GetContentViewX(contents_size.width());
     const int y =
         kDeskBarMiniViewsY - mini_views[0]->GetPreviewBorderInsets().top();
+    gfx::Size mini_view_size = mini_views[0]->GetPreferredSize();
     for (auto* mini_view : mini_views) {
       mini_view->SetBoundsRect(gfx::Rect(gfx::Point(x, y), mini_view_size));
       x += (mini_view_size.width() + kDeskBarMiniViewsSpacing);
@@ -297,7 +270,8 @@
     bar_view_->expanded_state_new_desk_button()->SetBoundsRect(
         gfx::Rect(gfx::Point(x, y), mini_view_size));
 
-    if (expanded_state_library_button) {
+    if (auto* expanded_state_library_button =
+            bar_view_->expanded_state_library_button()) {
       x += (mini_view_size.width() + kDeskBarMiniViewsSpacing);
       expanded_state_library_button->SetBoundsRect(
           gfx::Rect(gfx::Point(x, y), mini_view_size));
@@ -328,6 +302,52 @@
         gfx::Size(button_label_size.width(), desk_name_view->height())));
   }
 
+  // Updates the visibility of child views based on current `bar_view_`.
+  void UpdateChildViewsVisibility() {
+    if (chromeos::features::IsJellyrollEnabled()) {
+      auto* default_desk_button = bar_view_->default_desk_button();
+      auto* new_desk_button = bar_view_->new_desk_button();
+      auto* new_desk_button_label = bar_view_->new_desk_button_label();
+      auto* library_button = bar_view_->library_button();
+      auto* library_button_label = bar_view_->library_button_label();
+      const bool zero_state = bar_view_->IsZeroState();
+      default_desk_button->SetVisible(zero_state);
+      new_desk_button->SetVisible(true);
+      new_desk_button_label->SetVisible(
+          !zero_state &&
+          new_desk_button->state() == CrOSNextDeskIconButton::State::kActive);
+      if (library_button) {
+        library_button->SetVisible(bar_view_->ShouldShowLibraryUi());
+      }
+      if (library_button_label) {
+        library_button_label->SetVisible(
+            !zero_state &&
+            library_button->state() == CrOSNextDeskIconButton::State::kActive);
+      }
+    } else {
+      const bool zero_state = bar_view_->IsZeroState();
+      const bool show_library = bar_view_->ShouldShowLibraryUi();
+      auto* zero_state_default_desk_button =
+          bar_view_->zero_state_default_desk_button();
+      auto* zero_state_new_desk_button =
+          bar_view_->zero_state_new_desk_button();
+      auto* expanded_state_new_desk_button =
+          bar_view_->expanded_state_new_desk_button();
+      auto* zero_state_library_button = bar_view_->zero_state_library_button();
+      auto* expanded_state_library_button =
+          bar_view_->expanded_state_library_button();
+      zero_state_default_desk_button->SetVisible(zero_state);
+      zero_state_new_desk_button->SetVisible(zero_state);
+      expanded_state_new_desk_button->SetVisible(!zero_state);
+      if (zero_state_library_button) {
+        zero_state_library_button->SetVisible(zero_state && show_library);
+      }
+      if (expanded_state_library_button) {
+        expanded_state_library_button->SetVisible(!zero_state && show_library);
+      }
+    }
+  }
+
   // TODO(b/291622042): After CrOS Next is launched, remove function
   // `LayoutInternal`, and move this to `Layout`.
   void LayoutInternalCrOSNext(views::View* host) {
@@ -335,63 +355,44 @@
 
     const gfx::Rect scroll_bounds = bar_view_->scroll_view_->bounds();
 
-    auto* new_desk_button_label = bar_view_->new_desk_button_label();
-    auto* library_button_label = bar_view_->library_button_label();
+    // Update visibility of child views so that `GetPreferredSize()` returns
+    // correct size.
+    UpdateChildViewsVisibility();
+
+    const gfx::Size contents_size = host->GetPreferredSize();
 
     // `host` here is `scroll_view_contents_`.
     if (bar_view_->IsZeroState()) {
       host->SetBoundsRect(scroll_bounds);
 
-      new_desk_button_label->SetVisible(false);
-      if (library_button_label) {
-        library_button_label->SetVisible(false);
-      }
-
-      auto* default_desk_button = bar_view_->default_desk_button();
-      const gfx::Size default_desk_button_size =
-          default_desk_button->GetPreferredSize();
-
-      auto* new_desk_button = bar_view_->new_desk_button();
-      const gfx::Size new_desk_button_size =
-          new_desk_button->GetPreferredSize();
-
-      auto* library_button = bar_view_->library_button();
-      const gfx::Size library_button_size =
-          bar_view_->ShouldShowLibraryUi() ? library_button->GetPreferredSize()
-                                           : gfx::Size();
-      const int width_for_library_button =
-          bar_view_->ShouldShowLibraryUi()
-              ? library_button_size.width() + kDeskBarZeroStateButtonSpacing
-              : 0;
-
-      const int content_width =
-          default_desk_button_size.width() + kDeskBarZeroStateButtonSpacing +
-          new_desk_button_size.width() + width_for_library_button;
-      default_desk_button->SetBoundsRect(
-          gfx::Rect(gfx::Point((scroll_bounds.width() - content_width) / 2,
-                               kDeskBarZeroStateY),
-                    default_desk_button_size));
-
-      // Update this button's text since it may changes while removing a desk
-      // and going back to the zero state.
-      default_desk_button->UpdateLabelText();
+      // Update default desk button. In addition, update its button text since
+      // it may change while removing a desk and going back to the zero state.
       // Make sure default desk button is always visible while in zero state
       // bar.
-      default_desk_button->SetVisible(true);
+      auto* default_desk_button = bar_view_->default_desk_button();
+      default_desk_button->SetBoundsRect(gfx::Rect(
+          gfx::Point((scroll_bounds.width() - contents_size.width()) / 2,
+                     kDeskBarZeroStateY),
+          default_desk_button->GetPreferredSize()));
+      default_desk_button->UpdateLabelText();
+
+      // Update new desk button.
+      auto* new_desk_button = bar_view_->new_desk_button();
       new_desk_button->SetBoundsRect(
           gfx::Rect(gfx::Point(default_desk_button->bounds().right() +
                                    kDeskBarZeroStateButtonSpacing,
                                kDeskBarZeroStateY),
-                    new_desk_button_size));
+                    new_desk_button->GetPreferredSize()));
 
-      if (library_button) {
+      // Update library button.
+      if (auto* library_button = bar_view_->library_button()) {
         library_button->SetBoundsRect(
             gfx::Rect(gfx::Point(new_desk_button->bounds().right() +
                                      kDeskBarZeroStateButtonSpacing,
                                  kDeskBarZeroStateY),
-                      library_button_size));
-        library_button->SetVisible(bar_view_->ShouldShowLibraryUi());
+                      library_button->GetPreferredSize()));
       }
+
       return;
     }
 
@@ -399,6 +400,7 @@
     if (mini_views.empty()) {
       return;
     }
+
     // When RTL is enabled, we still want desks to be laid our in LTR, to match
     // the spatial order of desks. Therefore, we reverse the order of the mini
     // views before laying them out.
@@ -407,40 +409,18 @@
       base::ranges::reverse(mini_views);
     }
 
-    auto* library_button = bar_view_->library_button();
-    const bool library_button_visible =
-        library_button && library_button->GetVisible();
-    gfx::Size library_button_size =
-        library_button ? library_button->GetPreferredSize() : gfx::Size();
-
-    gfx::Size mini_view_size = mini_views[0]->GetPreferredSize();
-
-    auto* new_desk_button = bar_view_->new_desk_button();
-    gfx::Size new_desk_button_size = new_desk_button->GetPreferredSize();
-
-    // Content width is sum of the width of all views, and plus the spacing
-    // between the views, the focus ring's thickness and padding on each sides.
-    // TODO(b/301663756): consolidate size calculation for the desk bar and its
-    // scroll contents.
-    const int content_width =
-        mini_views.size() *
-            (mini_view_size.width() + kDeskBarMiniViewsSpacing) +
-        (new_desk_button_size.width() + kDeskBarMiniViewsSpacing) +
-        (library_button_visible ? 1 : 0) *
-            (library_button_size.width() + kDeskBarMiniViewsSpacing) -
-        kDeskBarMiniViewsSpacing +
-        kDeskBarDeskPreviewViewFocusRingThicknessAndPadding * 2;
-    width_ = std::max(scroll_bounds.width(), content_width);
+    width_ = std::max(scroll_bounds.width(), contents_size.width());
 
     // Update the size of the `host`, which is `scroll_view_contents_` here.
     // This is done to make sure its size can be updated on mini views' adding
     // or removing, then `scroll_view_` will know whether the contents need to
     // be scolled or not.
-    host->SetSize(gfx::Size(width_, scroll_bounds.height()));
+    host->SetSize(gfx::Size(width_, contents_size.height()));
 
     const int increment = is_rtl ? -1 : 1;
     const int y =
         kDeskBarMiniViewsY - mini_views[0]->GetPreviewBorderInsets().top();
+    const gfx::Size mini_view_size = mini_views[0]->GetPreferredSize();
     auto layout_mini_views = [&](int& x) {
       const int start = is_rtl ? mini_views.size() - 1 : 0;
       const int end = is_rtl ? -1 : mini_views.size();
@@ -456,49 +436,53 @@
     };
     auto* desk_name_view = mini_views[0]->desk_name_view();
     auto layout_new_desk_button = [&](int& x) {
+      auto* new_desk_button = bar_view_->new_desk_button();
+      const gfx::Size new_desk_button_size =
+          new_desk_button->GetPreferredSize();
       const gfx::Rect new_desk_button_bounds(gfx::Rect(
           gfx::Point(is_rtl ? x - new_desk_button_size.width() : x, y),
           new_desk_button_size));
       new_desk_button->SetBoundsRect(new_desk_button_bounds);
-      LayoutDeskIconButtonLabel(new_desk_button_label, new_desk_button_bounds,
-                                desk_name_view, IDS_ASH_DESKS_NEW_DESK_BUTTON);
-      new_desk_button_label->SetVisible(new_desk_button->state() ==
-                                        CrOSNextDeskIconButton::State::kActive);
+      LayoutDeskIconButtonLabel(bar_view_->new_desk_button_label(),
+                                new_desk_button_bounds, desk_name_view,
+                                IDS_ASH_DESKS_NEW_DESK_BUTTON);
       x +=
           (new_desk_button_size.width() + kDeskBarMiniViewsSpacing) * increment;
     };
     auto layout_library_button = [&](int& x) {
+      auto* library_button = bar_view_->library_button();
       if (!library_button) {
         return;
       }
+      const gfx::Size library_button_size =
+          library_button ? library_button->GetPreferredSize() : gfx::Size();
       const gfx::Rect library_button_bounds(
           gfx::Rect(gfx::Point(is_rtl ? x - library_button_size.width() : x, y),
                     library_button_size));
       library_button->SetBoundsRect(library_button_bounds);
       LayoutDeskIconButtonLabel(
-          library_button_label, library_button_bounds, desk_name_view,
+          bar_view_->library_button_label(), library_button_bounds,
+          desk_name_view,
           /*label_text_id=*/
           saved_desk_util::AreDesksTemplatesEnabled()
               ? IDS_ASH_DESKS_TEMPLATES_DESKS_BAR_BUTTON_LIBRARY
               : IDS_ASH_DESKS_TEMPLATES_DESKS_BAR_BUTTON_SAVED_FOR_LATER);
-      library_button_label->SetVisible(library_button->state() ==
-                                       CrOSNextDeskIconButton::State::kActive);
       x += (library_button_size.width() + kDeskBarMiniViewsSpacing) * increment;
     };
 
     // When the desk bar is in middle of bar shrink animation, the bounds of
-    // scroll view contents is actually wider than `content_width`. When RTL is
+    // scroll view contents is actually wider than `contents_width`. When RTL is
     // not on, we layout UIs from left to right with `x` indicating the current
     // available position to place the next UI; to make animation work for RTL,
     // we need to layout from right to left.
     // TODO(b/301665941): improve layout calculation for RTL.
     if (is_rtl) {
-      int x = width_ - GetContentViewX(content_width);
+      int x = width_ - GetContentViewX(contents_size.width());
       layout_library_button(x);
       layout_new_desk_button(x);
       layout_mini_views(x);
     } else {
-      int x = GetContentViewX(content_width);
+      int x = GetContentViewX(contents_size.width());
       layout_mini_views(x);
       layout_new_desk_button(x);
       layout_library_button(x);
@@ -518,7 +502,43 @@
 
   // views::LayoutManager:
   gfx::Size GetPreferredSize(const views::View* host) const override {
-    return gfx::Size(width_, bar_view_->bounds().height());
+    int width = 0;
+    std::vector<views::View*> child_views;
+
+    for (auto* mini_view : bar_view_->mini_views_) {
+      child_views.emplace_back(mini_view);
+    }
+
+    if (chromeos::features::IsJellyrollEnabled()) {
+      child_views.emplace_back(bar_view_->default_desk_button_);
+      child_views.emplace_back(bar_view_->new_desk_button_);
+      child_views.emplace_back(bar_view_->library_button_);
+    } else {
+      child_views.emplace_back(bar_view_->zero_state_default_desk_button_);
+      child_views.emplace_back(bar_view_->zero_state_new_desk_button_);
+      child_views.emplace_back(bar_view_->expanded_state_new_desk_button_);
+      child_views.emplace_back(bar_view_->zero_state_library_button_);
+      child_views.emplace_back(bar_view_->expanded_state_library_button_);
+    }
+
+    const int child_spacing =
+        bar_view_->state_ == DeskBarViewBase::State::kExpanded
+            ? kDeskBarMiniViewsSpacing
+            : kDeskBarZeroStateButtonSpacing;
+    for (auto* child : child_views) {
+      if (!child || !child->GetVisible()) {
+        continue;
+      }
+      if (width) {
+        width += child_spacing;
+      }
+      width += child->GetPreferredSize().width();
+    }
+    width += kDeskBarDeskPreviewViewFocusRingThicknessAndPadding * 2;
+
+    return gfx::Size(
+        width, DeskBarViewBase::GetPreferredBarHeight(
+                   bar_view_->root(), bar_view_->type_, bar_view_->state_));
   }
 
  private:
diff --git a/ash/wm/snap_group/snap_group_unittest.cc b/ash/wm/snap_group/snap_group_unittest.cc
index 44ff5475..7aa5034 100644
--- a/ash/wm/snap_group/snap_group_unittest.cc
+++ b/ash/wm/snap_group/snap_group_unittest.cc
@@ -1378,6 +1378,40 @@
       SnapGroupController::Get()->AreWindowsInSnapGroup(w1.get(), w2.get()));
 }
 
+TEST_F(SnapGroupEntryPointArm1Test, DoubleTapDivider) {
+  std::unique_ptr<aura::Window> w1(CreateTestWindow());
+  std::unique_ptr<aura::Window> w2(CreateTestWindow());
+  SnapTwoTestWindowsInArm1(w1.get(), w2.get());
+  auto* snap_group = SnapGroupController::Get()->GetTopmostSnapGroup();
+  EXPECT_TRUE(snap_group);
+  const auto* cached_primary_window = snap_group->window1();
+  const auto* cached_secondary_window = snap_group->window2();
+
+  // Test that double click on the divider swaps the windows.
+  const gfx::Point divider_center =
+      split_view_divider()
+          ->GetDividerBoundsInScreen(/*is_dragging=*/false)
+          .CenterPoint();
+  GetEventGenerator()->set_current_screen_location(divider_center);
+  GetEventGenerator()->DoubleClickLeftButton();
+  auto* new_primary_window = snap_group->window1();
+  auto* new_secondary_window = snap_group->window2();
+  EXPECT_TRUE(SnapGroupController::Get()->AreWindowsInSnapGroup(
+      new_primary_window, new_secondary_window));
+  EXPECT_EQ(new_primary_window, cached_secondary_window);
+  EXPECT_EQ(new_secondary_window, cached_primary_window);
+
+  // Switch to tablet mode. Test that double tap on the divider swaps the
+  // windows.
+  SwitchToTabletMode();
+  EXPECT_EQ(new_primary_window, split_view_controller()->primary_window());
+  EXPECT_EQ(new_secondary_window, split_view_controller()->secondary_window());
+  GetEventGenerator()->GestureTapAt(divider_center);
+  GetEventGenerator()->GestureTapAt(divider_center);
+  EXPECT_EQ(new_secondary_window, split_view_controller()->primary_window());
+  EXPECT_EQ(new_primary_window, split_view_controller()->secondary_window());
+}
+
 // Tests that removing a display during split view overview session doesn't
 // crash.
 TEST_F(SnapGroupEntryPointArm1Test, RemoveDisplay) {
@@ -3284,8 +3318,12 @@
           w2.get(), SplitViewController::SnapPosition::kSecondary);
       ASSERT_EQ(split_view_controller()->primary_window(), w1.get());
       ASSERT_EQ(split_view_controller()->secondary_window(), w2.get());
-      split_view_controller()->SwapWindows(
-          SplitViewController::SwapWindowsSource::kDoubleTap);
+      const gfx::Point divider_center =
+          split_view_divider()
+              ->GetDividerBoundsInScreen(/*is_dragging=*/false)
+              .CenterPoint();
+      GetEventGenerator()->GestureTapAt(divider_center);
+      GetEventGenerator()->GestureTapAt(divider_center);
       histogram_tester.ExpectBucketCount(
           kHistogramName, SplitViewController::SwapWindowsSource::kDoubleTap,
           1);
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc
index cf306e3..540a6acc 100644
--- a/ash/wm/splitview/split_view_controller.cc
+++ b/ash/wm/splitview/split_view_controller.cc
@@ -905,7 +905,7 @@
         ->OnOverviewItemDragEnded(/*snap=*/true);
   }
 
-  if (split_view_type_ == SplitViewType::kTabletType) {
+  if (split_view_divider_) {
     divider_position_ = GetClosestFixedDividerPosition();
     split_view_divider_->UpdateDividerBounds();
   }
diff --git a/ash/wm/splitview/split_view_controller_unittest.cc b/ash/wm/splitview/split_view_controller_unittest.cc
index ead74fb..2328b02 100644
--- a/ash/wm/splitview/split_view_controller_unittest.cc
+++ b/ash/wm/splitview/split_view_controller_unittest.cc
@@ -3277,7 +3277,7 @@
 
   // The left and right windows are observed by split view divider.
   aura::Window::Windows observed_windows =
-      split_view_divider()->observed_windows_for_testing();
+      split_view_divider()->observed_windows();
   EXPECT_TRUE(base::Contains(observed_windows, left_window.get()));
   EXPECT_TRUE(base::Contains(observed_windows, right_window.get()));
 }
diff --git a/ash/wm/splitview/split_view_divider.h b/ash/wm/splitview/split_view_divider.h
index 2ee080ad..1209490 100644
--- a/ash/wm/splitview/split_view_divider.h
+++ b/ash/wm/splitview/split_view_divider.h
@@ -52,8 +52,10 @@
       bool is_dragging);
 
   views::Widget* divider_widget() { return divider_widget_; }
-
   bool is_resizing_with_divider() const { return is_resizing_with_divider_; }
+  const aura::Window::Windows& observed_windows() const {
+    return observed_windows_;
+  }
 
   // Used by SplitViewController to immediately stop resizing in case of
   // external events (split view ending, tablet mode ending, etc.).
@@ -112,9 +114,6 @@
                                aura::Window* transient) override;
 
   SplitViewDividerView* divider_view_for_testing() { return divider_view_; }
-  const aura::Window::Windows& observed_windows_for_testing() const {
-    return observed_windows_;
-  }
 
  private:
   friend class SplitViewController;
diff --git a/ash/wm/splitview/split_view_divider_view.cc b/ash/wm/splitview/split_view_divider_view.cc
index 423c0bb..e9127bb 100644
--- a/ash/wm/splitview/split_view_divider_view.cc
+++ b/ash/wm/splitview/split_view_divider_view.cc
@@ -189,8 +189,7 @@
   divider_->EndResizeWithDivider(location);
   OnResizeStatusChanged();
   if (event.GetClickCount() == 2) {
-    split_view_controller_->SwapWindows(
-        SplitViewController::SwapWindowsSource::kDoubleTap);
+    SwapWindows();
   }
 }
 
@@ -200,8 +199,7 @@
   switch (event->type()) {
     case ui::ET_GESTURE_TAP:
       if (event->details().tap_count() == 2) {
-        split_view_controller_->SwapWindows(
-            SplitViewController::SwapWindowsSource::kDoubleTap);
+        SwapWindows();
       }
       break;
     case ui::ET_GESTURE_TAP_DOWN:
@@ -228,6 +226,23 @@
   return true;
 }
 
+void SplitViewDividerView::SwapWindows() {
+  if (IsSnapGroupEnabledInClamshellMode()) {
+    // TODO(sophiewen): Consider adding a reference to `snap_group_` in
+    // `SplitViewDivider` when multiple groups are added.
+    // The divider would only be created between two windows.
+    CHECK_EQ(2u, divider_->observed_windows().size());
+    aura::Window* window = divider_->observed_windows().front();
+    if (SnapGroup* snap_group =
+            SnapGroupController::Get()->GetSnapGroupForGivenWindow(window)) {
+      snap_group->SwapWindows();
+    }
+    return;
+  }
+  split_view_controller_->SwapWindows(
+      SplitViewController::SwapWindowsSource::kDoubleTap);
+}
+
 void SplitViewDividerView::OnResizeStatusChanged() {
   // It's possible that when this function is called, split view mode has
   // been ended, and the divider widget is to be deleted soon. In this case
diff --git a/ash/wm/splitview/split_view_divider_view.h b/ash/wm/splitview/split_view_divider_view.h
index db12d82..a99d6d7d 100644
--- a/ash/wm/splitview/split_view_divider_view.h
+++ b/ash/wm/splitview/split_view_divider_view.h
@@ -56,6 +56,8 @@
   }
 
  private:
+  void SwapWindows();
+
   void OnResizeStatusChanged();
 
   // Called when the `kebab_button_` is pressed which toggles between showing or
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 8bd239100..c450cf92 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -4124,6 +4124,11 @@
   nocompile_source_set("base_nocompile_tests_new") {
     sources = [
       "callback_list_nocompile.nc",
+      "containers/buffer_iterator_nocompile.nc",
+      "containers/checked_iterators_nocompile.nc",
+      "containers/contains_nocompile.nc",
+      "containers/enum_set_nocompile.nc",
+      "containers/span_nocompile.nc",
       "memory/weak_ptr_nocompile.nc",
       "no_destructor_nocompile.nc",
       "observer_list_nocompile.nc",
@@ -4142,25 +4147,20 @@
 if (enable_nocompile_tests) {
   nocompile_test("base_nocompile_tests") {
     sources = [
-      "allocator/partition_allocator/src/partition_alloc/partition_alloc_base/thread_annotations_pa_unittest.nc",
-      "allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.nc",
-      "allocator/partition_allocator/src/partition_alloc/pointers/raw_ref_unittest.nc",
-      "containers/buffer_iterator_unittest.nc",
-      "containers/checked_iterators_unittest.nc",
-      "containers/contains_unittest.nc",
-      "containers/enum_set_unittest.nc",
-      "containers/span_unittest.nc",
-      "debug/crash_logging_unittest.nc",
-      "functional/bind_unittest.nc",
-      "functional/callback_unittest.nc",
-      "functional/function_ref_unittest.nc",
-      "functional/overloaded_unittest.nc",
-      "memory/ref_counted_unittest.nc",
-      "metrics/field_trial_params_unittest.nc",
-      "metrics/histogram_unittest.nc",
-      "strings/string_piece_unittest.nc",
-      "traits_bag_unittest.nc",
-      "types/pass_key_unittest.nc",
+      "allocator/partition_allocator/src/partition_alloc/partition_alloc_base/thread_annotations_pa_nocompile.nc",
+      "allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_nocompile.nc",
+      "allocator/partition_allocator/src/partition_alloc/pointers/raw_ref_nocompile.nc",
+      "debug/crash_logging_nocompile.nc",
+      "functional/bind_nocompile.nc",
+      "functional/callback_nocompile.nc",
+      "functional/function_ref_nocompile.nc",
+      "functional/overloaded_nocompile.nc",
+      "memory/ref_counted_nocompile.nc",
+      "metrics/field_trial_params_nocompile.nc",
+      "metrics/histogram_nocompile.nc",
+      "strings/string_piece_nocompile.nc",
+      "traits_bag_nocompile.nc",
+      "types/pass_key_nocompile.nc",
     ]
 
     deps = [
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/thread_annotations_pa_unittest.nc b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/thread_annotations_pa_nocompile.nc
similarity index 100%
rename from base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/thread_annotations_pa_unittest.nc
rename to base/allocator/partition_allocator/src/partition_alloc/partition_alloc_base/thread_annotations_pa_nocompile.nc
diff --git a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.nc b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_nocompile.nc
similarity index 100%
rename from base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.nc
rename to base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_nocompile.nc
diff --git a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.cc b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.cc
index eb449b4..fdf92412f 100644
--- a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.cc
+++ b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_unittest.cc
@@ -1548,6 +1548,13 @@
   EXPECT_EQ(ptr.get(), &v1);
 }
 
+#if defined(COMPILER_GCC) && !defined(__clang__)
+// In GCC this test will optimize the return value of the constructor, so
+// assert fails. Disable optimizations to verify uninitialized attribute works
+// as expected.
+#pragma GCC push_options
+#pragma GCC optimize("O0")
+#endif
 TEST_F(RawPtrTest, AllowUninitialized) {
   constexpr uintptr_t kPattern = 0x12345678;
   uintptr_t storage = kPattern;
@@ -1555,6 +1562,9 @@
   new (&storage) CountingRawPtrUninitialized<int>;
   EXPECT_EQ(storage, kPattern);
 }
+#if defined(COMPILER_GCC) && !defined(__clang__)
+#pragma GCC pop_options
+#endif
 
 }  // namespace
 
diff --git a/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ref_unittest.nc b/base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ref_nocompile.nc
similarity index 100%
rename from base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ref_unittest.nc
rename to base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ref_nocompile.nc
diff --git a/base/containers/buffer_iterator_nocompile.nc b/base/containers/buffer_iterator_nocompile.nc
new file mode 100644
index 0000000..9c2ae4b6
--- /dev/null
+++ b/base/containers/buffer_iterator_nocompile.nc
@@ -0,0 +1,58 @@
+// Copyright 2019 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This is a "No Compile Test" suite.
+// http://dev.chromium.org/developers/testing/no-compile-tests
+
+#include "base/containers/buffer_iterator.h"
+
+#include <stdint.h>
+
+#include <string>
+
+namespace base {
+
+class Complex {
+ public:
+  Complex() : string_("Moo") {}
+
+ private:
+  std::string string_;
+};
+
+void CreateTypeUint16() {
+  constexpr size_t size = 64;
+  uint16_t data[size];
+  BufferIterator<uint16_t> iterator(data, size);  // expected-error@*:* {{Underlying buffer type must be char-type.}}
+}
+
+void ComplexMutableObject() {
+  constexpr size_t size = 64;
+  uint8_t data[size];
+  BufferIterator<uint8_t> iterator(data, size);
+  Complex* c = iterator.MutableObject<Complex>();  // expected-error {{no matching member function for call to 'MutableObject'}}
+}
+
+void ComplexObject() {
+  constexpr size_t size = 64;
+  uint8_t data[size];
+  BufferIterator<uint8_t> iterator(data, size);
+  const Complex* c = iterator.Object<Complex>();  // expected-error {{no matching member function for call to 'Object'}}
+}
+
+void ComplexMutableSpan() {
+  constexpr size_t size = 64;
+  uint8_t data[size];
+  BufferIterator<uint8_t> iterator(data, size);
+  base::span<Complex> s = iterator.MutableSpan<Complex>(3);  // expected-error {{no matching member function for call to 'MutableSpan'}}
+}
+
+void ComplexSpan() {
+  constexpr size_t size = 64;
+  uint8_t data[size];
+  BufferIterator<uint8_t> iterator(data, size);
+  base::span<const Complex> s = iterator.Span<Complex>();  // expected-error {{no matching member function for call to 'Span'}}
+}
+
+}  // namespace base
diff --git a/base/containers/buffer_iterator_unittest.nc b/base/containers/buffer_iterator_unittest.nc
deleted file mode 100644
index c99c50e..0000000
--- a/base/containers/buffer_iterator_unittest.nc
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2019 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This is a "No Compile Test" suite.
-// http://dev.chromium.org/developers/testing/no-compile-tests
-
-#include "base/containers/buffer_iterator.h"
-
-#include <stdint.h>
-
-#include <string>
-
-namespace base {
-
-class Complex {
- public:
-  Complex() : string_("Moo") {}
-
- private:
-  std::string string_;
-};
-
-#if defined(NCTEST_BUFFER_ITERATOR_CREATE_TYPE_UINT16)  // [r"fatal error: static_assert failed due to requirement 'std::is_same_v<unsigned short, char> || std::is_same_v<unsigned short, unsigned char>': Underlying buffer type must be char-type."]
-
-void WontCompile() {
-  constexpr size_t size = 64;
-  uint16_t data[size];
-  BufferIterator<uint16_t> iterator(data, size);
-}
-
-#elif defined(NCTEST_BUFFER_ITERATOR_COMPLEX_MUTABLE_OBJECT)  // [r"no matching member function for call to 'MutableObject'"]
-
-void WontCompile() {
-  constexpr size_t size = 64;
-  uint8_t data[size];
-  BufferIterator<uint8_t> iterator(data, size);
-  Complex* c = iterator.MutableObject<Complex>();
-}
-
-#elif defined(NCTEST_BUFFER_ITERATOR_COMPLEX_OBJECT)  // [r"no matching member function for call to 'Object'"]
-
-void WontCompile() {
-  constexpr size_t size = 64;
-  uint8_t data[size];
-  BufferIterator<uint8_t> iterator(data, size);
-  const Complex* c = iterator.Object<Complex>();
-}
-
-#elif defined(NCTEST_BUFFER_ITERATOR_COMPLEX_MUTABLE_SPAN)  // [r"no matching member function for call to 'MutableSpan'"]
-
-void WontCompile() {
-  constexpr size_t size = 64;
-  uint8_t data[size];
-  BufferIterator<uint8_t> iterator(data, size);
-  base::span<Complex> s = iterator.MutableSpan<Complex>(3);
-}
-
-#elif defined(NCTEST_BUFFER_ITERATOR_COMPLEX_SPAN)  // [r"no matching member function for call to 'Span'"]
-
-void WontCompile() {
-  constexpr size_t size = 64;
-  uint8_t data[size];
-  BufferIterator<uint8_t> iterator(data, size);
-  base::span<const Complex> s = iterator.Span<Complex>();
-}
-
-#endif
-
-}  // namespace base
diff --git a/base/containers/checked_iterators_nocompile.nc b/base/containers/checked_iterators_nocompile.nc
new file mode 100644
index 0000000..dec0d4e
--- /dev/null
+++ b/base/containers/checked_iterators_nocompile.nc
@@ -0,0 +1,97 @@
+// Copyright 2019 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This is a "No Compile Test" suite.
+// http://dev.chromium.org/developers/testing/no-compile-tests
+
+#include "base/containers/checked_iterators.h"
+
+namespace base {
+
+constexpr int kArray1[] = {1, 2, 3, 4, 5};
+constexpr int kArray2[] = {1, 2, 3, 4, 5};
+
+constexpr auto GetBeginIter() {
+  return CheckedContiguousIterator<const int>(kArray1, kArray1 + 5);
+}
+
+constexpr auto GetEndIter() {
+  return CheckedContiguousIterator<const int>(kArray1, kArray1 + 5,
+                                              kArray1 + 5);
+}
+
+void ConstructorOrdering() {
+  // Start can't be larger than end.
+  constexpr CheckedContiguousIterator<const int> iter1(kArray1 + 1, kArray1);  // expected-error {{constexpr variable 'iter1' must be initialized by a constant expression}}
+
+  // Current can't be larger than start.
+  constexpr CheckedContiguousIterator<const int> iter2(kArray1 + 1, kArray1,  // expected-error {{constexpr variable 'iter2' must be initialized by a constant expression}}
+                                                       kArray1 + 5);
+
+  // Current can't be larger than end.
+  constexpr CheckedContiguousIterator<const int> iter3(kArray1, kArray1 + 2,  // expected-error {{constexpr variable 'iter3' must be initialized by a constant expression}}
+                                                       kArray1 + 1);
+}
+
+void CompareItersFromDifferentContainers() {
+  // Can't compare iterators into different containers.
+  constexpr auto iter1 = GetBeginIter();
+  constexpr CheckedContiguousIterator<const int> iter2(kArray2, kArray2 + 5);
+  constexpr bool equal = iter1 == iter2;          // expected-error {{constexpr variable 'equal' must be initialized by a constant expression}}
+  constexpr bool not_equal = iter1 != iter2;      // expected-error {{constexpr variable 'not_equal' must be initialized by a constant expression}}
+  constexpr bool less_than = iter1 < iter2;       // expected-error {{constexpr variable 'less_than' must be initialized by a constant expression}}
+  constexpr bool less_equal = iter1 <= iter2;     // expected-error {{constexpr variable 'less_equal' must be initialized by a constant expression}}
+  constexpr bool greater_than = iter1 > iter2;    // expected-error {{constexpr variable 'greater_than' must be initialized by a constant expression}}
+  constexpr bool greater_equal = iter1 >= iter2;  // expected-error {{constexpr variable 'greater_equal' must be initialized by a constant expression}}
+  constexpr auto difference = iter1 - iter2;      // expected-error {{constexpr variable 'difference' must be initialized by a constant expression}}
+}
+
+void DecrementBegin() {
+  constexpr auto past_begin1 = --GetBeginIter();        // expected-error {{constexpr variable 'past_begin1' must be initialized by a constant expression}}
+  constexpr auto past_begin2 = GetBeginIter()--;        // expected-error {{constexpr variable 'past_begin2' must be initialized by a constant expression}}
+  constexpr auto past_begin3 = (GetBeginIter() += -1);  // expected-error {{constexpr variable 'past_begin3' must be initialized by a constant expression}}
+  constexpr auto past_begin4 = GetBeginIter() + -1;     // expected-error {{constexpr variable 'past_begin4' must be initialized by a constant expression}}
+  constexpr auto past_begin5 = (GetBeginIter() -= 1);   // expected-error {{constexpr variable 'past_begin5' must be initialized by a constant expression}}
+  constexpr auto past_begin6 = GetBeginIter() - 1;      // expected-error {{constexpr variable 'past_begin6' must be initialized by a constant expression}}
+}
+
+void IncrementBeginPastEnd() {
+  constexpr auto past_end1 = (GetBeginIter() += 6);   // expected-error {{constexpr variable 'past_end1' must be initialized by a constant expression}}
+  constexpr auto past_end2 = GetBeginIter() + 6;      // expected-error {{constexpr variable 'past_end2' must be initialized by a constant expression}}
+  constexpr auto past_end3 = (GetBeginIter() -= -6);  // expected-error {{constexpr variable 'past_end3' must be initialized by a constant expression}}
+  constexpr auto past_end4 = GetBeginIter() - -6;     // expected-error {{constexpr variable 'past_end4' must be initialized by a constant expression}}
+}
+
+void IncrementEnd() {
+  constexpr auto past_end1 = ++GetEndIter();        // expected-error {{constexpr variable 'past_end1' must be initialized by a constant expression}}
+  constexpr auto past_end2 = GetEndIter()++;        // expected-error {{constexpr variable 'past_end2' must be initialized by a constant expression}}
+  constexpr auto past_end3 = (GetEndIter() += 1);   // expected-error {{constexpr variable 'past_end3' must be initialized by a constant expression}}
+  constexpr auto past_end4 = GetEndIter() + 1;      // expected-error {{constexpr variable 'past_end4' must be initialized by a constant expression}}
+  constexpr auto past_end5 = (GetEndIter() -= -1);  // expected-error {{constexpr variable 'past_end5' must be initialized by a constant expression}}
+  constexpr auto past_end6 = GetEndIter() - -1;     // expected-error {{constexpr variable 'past_end6' must be initialized by a constant expression}}
+}
+
+void DecrementEndPastBegin() {
+  constexpr auto past_begin1 = (GetEndIter() += -6);  // expected-error {{constexpr variable 'past_begin1' must be initialized by a constant expression}}
+  constexpr auto past_begin2 = GetEndIter() + -6;     // expected-error {{constexpr variable 'past_begin2' must be initialized by a constant expression}}
+  constexpr auto past_begin3 = (GetEndIter() -= 6);   // expected-error {{constexpr variable 'past_begin3' must be initialized by a constant expression}}
+  constexpr auto past_begin4 = GetEndIter() - 6;      // expected-error {{constexpr variable 'past_begin4' must be initialized by a constant expression}}
+}
+
+void DerefBegin() {
+  // Can't use a negative index in operator[].
+  constexpr auto& ref1 = GetBeginIter()[-1];  // expected-error {{constexpr variable 'ref1' must be initialized by a constant expression}}
+
+  // Can't use a operator[] to deref the end.
+  constexpr auto& ref2 = GetBeginIter()[5];  // expected-error {{constexpr variable 'ref2' must be initialized by a constant expression}}
+}
+
+void DerefEnd() {
+  // Can't dereference the end iterator.
+  constexpr auto& ref1 = *GetEndIter();             // expected-error {{constexpr variable 'ref1' must be initialized by a constant expression}}
+  constexpr auto* ptr = GetEndIter().operator->();  // expected-error {{constexpr variable 'ptr' must be initialized by a constant expression}}
+  constexpr auto& ref2 = GetEndIter()[0];           // expected-error {{constexpr variable 'ref2' must be initialized by a constant expression}}
+}
+
+}  // namespace base
diff --git a/base/containers/checked_iterators_unittest.nc b/base/containers/checked_iterators_unittest.nc
deleted file mode 100644
index 99d97f51..0000000
--- a/base/containers/checked_iterators_unittest.nc
+++ /dev/null
@@ -1,325 +0,0 @@
-// Copyright 2019 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This is a "No Compile Test" suite.
-// http://dev.chromium.org/developers/testing/no-compile-tests
-
-#include "base/containers/checked_iterators.h"
-
-namespace base {
-
-#if defined(NCTEST_CHECKED_ITERATORS_CONSTRUCTOR_START_END)  // [r"constexpr variable 'iter' must be initialized by a constant expression"]
-
-constexpr int kArray[] = {1, 2, 3, 4, 5};
-
-void WontCompile() {
-  // start can't be larger than end
-  constexpr CheckedContiguousIterator<const int> iter(kArray + 1, kArray);
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_CONSTRUCTOR_START_CURRENT)  // [r"constexpr variable 'iter' must be initialized by a constant expression"]
-
-constexpr int kArray[] = {1, 2, 3, 4, 5};
-
-void WontCompile() {
-  // current can't be larger than start
-  constexpr CheckedContiguousIterator<const int> iter(kArray + 1, kArray, kArray + 5);
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_CONSTRUCTOR_CURRENT_END)  // [r"constexpr variable 'iter' must be initialized by a constant expression"]
-
-constexpr int kArray[] = {1, 2, 3, 4, 5};
-
-void WontCompile() {
-  // current can't be larger than end
-  constexpr CheckedContiguousIterator<const int> iter(kArray, kArray + 2, kArray + 1);
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_EQ_DIFFERENT_ITER)  // [r"constexpr variable 'equal' must be initialized by a constant expression"]
-
-constexpr int kArray1[] = {1, 2, 3, 4, 5};
-constexpr int kArray2[] = {1, 2, 3, 4, 5};
-
-void WontCompile() {
-  // Can't compare iterators into different containers
-  constexpr CheckedContiguousIterator<const int> iter1(kArray1, kArray1 + 5);
-  constexpr CheckedContiguousIterator<const int> iter2(kArray2, kArray2 + 5);
-  constexpr bool equal = iter1 == iter2;
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_NE_DIFFERENT_ITER)  // [r"constexpr variable 'not_equal' must be initialized by a constant expression"]
-
-constexpr int kArray1[] = {1, 2, 3, 4, 5};
-constexpr int kArray2[] = {1, 2, 3, 4, 5};
-
-void WontCompile() {
-  // Can't compare iterators into different containers
-  constexpr CheckedContiguousIterator<const int> iter1(kArray1, kArray1 + 5);
-  constexpr CheckedContiguousIterator<const int> iter2(kArray2, kArray2 + 5);
-  constexpr bool not_equal = iter1 != iter2;
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_LT_DIFFERENT_ITER)  // [r"constexpr variable 'less_than' must be initialized by a constant expression"]
-
-constexpr int kArray1[] = {1, 2, 3, 4, 5};
-constexpr int kArray2[] = {1, 2, 3, 4, 5};
-
-void WontCompile() {
-  // Can't compare iterators into different containers
-  constexpr CheckedContiguousIterator<const int> iter1(kArray1, kArray1 + 5);
-  constexpr CheckedContiguousIterator<const int> iter2(kArray2, kArray2 + 5);
-  constexpr bool less_than = iter1 < iter2;
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_LE_DIFFERENT_ITER)  // [r"constexpr variable 'less_equal' must be initialized by a constant expression"]
-
-constexpr int kArray1[] = {1, 2, 3, 4, 5};
-constexpr int kArray2[] = {1, 2, 3, 4, 5};
-
-void WontCompile() {
-  // Can't compare iterators into different containers
-  constexpr CheckedContiguousIterator<const int> iter1(kArray1, kArray1 + 5);
-  constexpr CheckedContiguousIterator<const int> iter2(kArray2, kArray2 + 5);
-  constexpr bool less_equal = iter1 <= iter2;
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_GT_DIFFERENT_ITER)  // [r"constexpr variable 'greater_than' must be initialized by a constant expression"]
-
-constexpr int kArray1[] = {1, 2, 3, 4, 5};
-constexpr int kArray2[] = {1, 2, 3, 4, 5};
-
-void WontCompile() {
-  // Can't compare iterators into different containers
-  constexpr CheckedContiguousIterator<const int> iter1(kArray1, kArray1 + 5);
-  constexpr CheckedContiguousIterator<const int> iter2(kArray2, kArray2 + 5);
-  constexpr bool greater_than = iter1 > iter2;
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_GE_DIFFERENT_ITER)  // [r"constexpr variable 'greater_equal' must be initialized by a constant expression"]
-
-constexpr int kArray1[] = {1, 2, 3, 4, 5};
-constexpr int kArray2[] = {1, 2, 3, 4, 5};
-
-void WontCompile() {
-  // Can't compare iterators into different containers
-  constexpr CheckedContiguousIterator<const int> iter1(kArray1, kArray1 + 5);
-  constexpr CheckedContiguousIterator<const int> iter2(kArray2, kArray2 + 5);
-  constexpr bool greater_equal = iter1 >= iter2;
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_PRE_INCR_END)  // [r"constexpr variable 'pre_incr' must be initialized by a constant expression"]
-
-constexpr int kArray[] = {1, 2, 3, 4, 5};
-
-constexpr int PreIncr() {
-  // Can't pre-increment the end iterator.
-  CheckedContiguousIterator<const int> end_iter(kArray, kArray + 5, kArray + 5);
-  ++end_iter;
-  return 0;
-}
-
-void WontCompile() {
-  constexpr int pre_incr = PreIncr();
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_POST_INCR_END)  // [r"constexpr variable 'post_incr' must be initialized by a constant expression"]
-
-constexpr int kArray[] = {1, 2, 3, 4, 5};
-
-constexpr int PostIncr() {
-  // Can't post-increment the end iterator.
-  CheckedContiguousIterator<const int> end_iter(kArray, kArray + 5, kArray + 5);
-  end_iter++;
-  return 0;
-}
-
-void WontCompile() {
-  constexpr int post_incr = PostIncr();
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_PRE_DECR_BEGIN)  // [r"constexpr variable 'pre_decr' must be initialized by a constant expression"]
-
-constexpr int kArray[] = {1, 2, 3, 4, 5};
-
-constexpr int PreDecr() {
-  // Can't pre-decrement the begin iterator.
-  CheckedContiguousIterator<const int> begin_iter(kArray, kArray + 5);
-  --begin_iter;
-  return 0;
-}
-
-void WontCompile() {
-  constexpr int pre_decr = PreDecr();
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_POST_DECR_BEGIN)  // [r"constexpr variable 'post_decr' must be initialized by a constant expression"]
-
-constexpr int kArray[] = {1, 2, 3, 4, 5};
-
-constexpr int PostDecr() {
-  // Can't post-decrement the begin iterator.
-  CheckedContiguousIterator<const int> begin_iter(kArray, kArray + 5);
-  begin_iter--;
-  return 0;
-}
-
-void WontCompile() {
-  constexpr int post_decr = PostDecr();
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_INCR_PAST_END)  // [r"constexpr variable 'incr_past_end' must be initialized by a constant expression"]
-
-constexpr int kArray[] = {1, 2, 3, 4, 5};
-
-constexpr int IncrPastEnd() {
-  // Can't increment iterator past the end.
-  CheckedContiguousIterator<const int> iter(kArray, kArray + 5);
-  iter += 6;
-  return 0;
-}
-
-void WontCompile() {
-  constexpr int incr_past_end = IncrPastEnd();
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_DECR_PAST_BEGIN)  // [r"constexpr variable 'decr_past_begin' must be initialized by a constant expression"]
-
-constexpr int kArray[] = {1, 2, 3, 4, 5};
-
-constexpr int DecrPastBegin() {
-  // Can't decrement iterator past the begin.
-  CheckedContiguousIterator<const int> iter(kArray, kArray + 5);
-  iter += -1;
-  return 0;
-}
-
-void WontCompile() {
-  constexpr int decr_past_begin = DecrPastBegin();
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_INCR_PAST_END_2)  // [r"constexpr variable 'iter_past_end' must be initialized by a constant expression"]
-
-constexpr int kArray[] = {1, 2, 3, 4, 5};
-
-void WontCompile() {
-  // Can't increment iterator past the end.
-  constexpr CheckedContiguousIterator<const int> iter(kArray, kArray + 5);
-  constexpr auto iter_past_end = iter + 6;
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_DECR_PAST_BEGIN_2)  // [r"constexpr variable 'iter_past_begin' must be initialized by a constant expression"]
-
-constexpr int kArray[] = {1, 2, 3, 4, 5};
-
-void WontCompile() {
-  // Can't decrement iterator past the begin.
-  constexpr CheckedContiguousIterator<const int> iter(kArray, kArray + 5);
-  constexpr auto iter_past_begin = iter + (-1);
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_DECR_PAST_BEGIN_3)  // [r"constexpr variable 'decr_past_begin' must be initialized by a constant expression"]
-
-constexpr int kArray[] = {1, 2, 3, 4, 5};
-
-constexpr int DecrPastBegin() {
-  // Can't decrement iterator past the begin.
-  CheckedContiguousIterator<const int> iter(kArray, kArray + 5);
-  iter -= 1;
-  return 0;
-}
-
-void WontCompile() {
-  constexpr int decr_past_begin = DecrPastBegin();
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_INCR_PAST_END_3)  // [r"constexpr variable 'incr_past_end' must be initialized by a constant expression"]
-
-constexpr int kArray[] = {1, 2, 3, 4, 5};
-
-constexpr int IncrPastEnd() {
-  // Can't increment iterator past the end.
-  CheckedContiguousIterator<const int> iter(kArray, kArray + 5);
-  iter -= (-6);
-  return 0;
-}
-
-void WontCompile() {
-  constexpr int incr_past_end = IncrPastEnd();
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_DECR_PAST_BEGIN_4)  // [r"constexpr variable 'iter_past_begin' must be initialized by a constant expression"]
-
-constexpr int kArray[] = {1, 2, 3, 4, 5};
-
-void WontCompile() {
-  // Can't decrement iterator past the begin.
-  constexpr CheckedContiguousIterator<const int> iter(kArray, kArray + 5);
-  constexpr auto iter_past_begin = iter - 1;
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_INCR_PAST_END_4)  // [r"constexpr variable 'iter_past_end' must be initialized by a constant expression"]
-
-constexpr int kArray[] = {1, 2, 3, 4, 5};
-
-void WontCompile() {
-  // Can't increment iterator past the end.
-  constexpr CheckedContiguousIterator<const int> iter(kArray, kArray + 5);
-  constexpr auto iter_past_end = iter - (-6);
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_DIFFERENCE_DIFFERENT_ITER)  // [r"constexpr variable 'difference' must be initialized by a constant expression"]
-
-constexpr int kArray1[] = {1, 2, 3, 4, 5};
-constexpr int kArray2[] = {1, 2, 3, 4, 5};
-
-void WontCompile() {
-  // Can't compare iterators into different containers
-  constexpr CheckedContiguousIterator<const int> iter1(kArray1, kArray1 + 5);
-  constexpr CheckedContiguousIterator<const int> iter2(kArray2, kArray2 + 5);
-  constexpr auto difference = iter1 - iter2;
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_STAR_END)  // [r"constexpr variable 'ref' must be initialized by a constant expression"]
-
-constexpr int kArray[] = {1, 2, 3, 4, 5};
-
-void WontCompile() {
-  // Can't dereference the end iterator by star.
-  constexpr CheckedContiguousIterator<const int> end_iter(kArray, kArray + 5, kArray + 5);
-  constexpr auto& ref = *end_iter;
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_ARROW_END)  // [r"constexpr variable 'ptr' must be initialized by a constant expression"]
-
-constexpr int kArray[] = {1, 2, 3, 4, 5};
-
-void WontCompile() {
-  // Can't dereference the end iterator by arrow.
-  constexpr CheckedContiguousIterator<const int> end_iter(kArray, kArray + 5, kArray + 5);
-  constexpr auto* ptr = end_iter.operator->();
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_NEGATIVE_OPERATOR_AT)  // [r"constexpr variable 'ref' must be initialized by a constant expression"]
-
-constexpr int kArray[] = {1, 2, 3, 4, 5};
-
-void WontCompile() {
-  // Can't use a negative index in operator[].
-  constexpr CheckedContiguousIterator<const int> iter(kArray, kArray + 5);
-  constexpr auto& ref = iter[-1];
-}
-
-#elif defined(NCTEST_CHECKED_ITERATORS_OPERATOR_AT_END)  // [r"constexpr variable 'ref' must be initialized by a constant expression"]
-
-constexpr int kArray[] = {1, 2, 3, 4, 5};
-
-void WontCompile() {
-  // Can't use a operator[] to deref the end.
-  constexpr CheckedContiguousIterator<const int> iter(kArray, kArray + 5);
-  constexpr auto& ref = iter[5];
-}
-
-#endif
-
-}  // namespace base
diff --git a/base/containers/contains_unittest.nc b/base/containers/contains_nocompile.nc
similarity index 85%
rename from base/containers/contains_unittest.nc
rename to base/containers/contains_nocompile.nc
index 98e9fcb..b4b578b 100644
--- a/base/containers/contains_unittest.nc
+++ b/base/containers/contains_nocompile.nc
@@ -22,12 +22,10 @@
 // (in this case `set.find()` accepts any type that is comparable to a
 // std::string), or pass an explicit projection parameter to Contains, at which
 // point it will always perform a linear search.
-#if defined(NCTEST_CONTAINS_UNEXPECTED_LINEAR_SEARCH)  // [r"Error: About to perform linear search on an associative container."]
-void WontCompile() {
+void UnexpectedLinearSearch() {
   constexpr StringPiece kFoo = "foo";
   std::set<std::string> set = {"foo", "bar", "baz"};
-  Contains(set, kFoo);
+  Contains(set, kFoo);  // expected-error@*:* {{About to perform linear search on an associative container}}
 }
-#endif
 
 }  // namespace base
diff --git a/base/containers/enum_set_unittest.nc b/base/containers/enum_set_nocompile.nc
similarity index 76%
rename from base/containers/enum_set_unittest.nc
rename to base/containers/enum_set_nocompile.nc
index 076dad4..c4c54fc 100644
--- a/base/containers/enum_set_unittest.nc
+++ b/base/containers/enum_set_nocompile.nc
@@ -10,9 +10,7 @@
 namespace base {
 namespace {
 
-#if defined(NCTEST_ALL_METHOD_DISALLOWED_ON_LARGE_SPARSE_ENUM) // [r"fatal error: constexpr variable 'set' must be initialized by a constant expression"]
-
-size_t WontCompile() {
+size_t LargeSparseEnum() {
   enum class TestEnumSparse {
     TEST_1 = 1,
     TEST_MIN = 1,
@@ -25,11 +23,9 @@
 
   // TestEnumSparseSet::All() does not compile as constexpr because there are
   // more than 64 possible values.
-  constexpr auto set = TestEnumSparseSet::All();
+  constexpr auto set = TestEnumSparseSet::All();  // expected-error {{constexpr variable 'set' must be initialized by a constant expression}}
   return set.Size();
 }
 
-#endif
-
 }  // namespace
 }  // namespace base
diff --git a/base/containers/span_nocompile.nc b/base/containers/span_nocompile.nc
new file mode 100644
index 0000000..8b0a5957
--- /dev/null
+++ b/base/containers/span_nocompile.nc
@@ -0,0 +1,175 @@
+// 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.
+
+// This is a "No Compile Test" suite.
+// http://dev.chromium.org/developers/testing/no-compile-tests
+
+#include "base/containers/span.h"
+
+#include <array>
+#include <set>
+#include <vector>
+
+#include "base/strings/string_piece.h"
+
+namespace base {
+
+class Base {
+};
+
+class Derived : Base {
+};
+
+// A default constructed span must have an extent of 0 or dynamic_extent.
+void DefaultSpanWithNonZeroStaticExtentDisallowed() {
+  span<int, 1u> span;  // expected-error@*:* {{Invalid Extent}}
+}
+
+// A span with static extent constructed from an array must match the size of
+// the array.
+void SpanFromArrayWithNonMatchingStaticExtentDisallowed() {
+  int array[] = {1, 2, 3};
+  span<int, 1u> span(array);  // expected-error {{no matching constructor for initialization of 'span<int, 1U>'}}
+}
+
+// A span with static extent constructed from another span must match the
+// extent.
+void SpanFromOtherSpanWithMismatchingExtentDisallowed() {
+  std::array<int, 3> array = {1, 2, 3};
+  span<int, 3u> span3(array);
+  span<int, 4u> span4(span3);  // expected-error {{no matching constructor for initialization of 'span<int, 4U>'}}
+}
+
+// Converting a dynamic span to a static span should not be allowed.
+void DynamicSpanToStaticSpanDisallowed() {
+  span<int> dynamic_span;
+  span<int, 3u> static_span(dynamic_span);  // expected-error {{no matching constructor for initialization of 'span<int, 3U>'}}
+}
+
+// Internally, this is represented as a pointer to pointers to Derived. An
+// implicit conversion to a pointer to pointers to Base must not be allowed.
+// If it were allowed, then something like this would be possible:
+//   Cat** cats = GetCats();
+//   Animals** animals = cats;
+//   animals[0] = new Dog();  // Uh oh!
+void DerivedToBaseConversionDisallowed() {
+  span<Derived*> derived_span;
+  span<Base*> base_span(derived_span);  // expected-error {{no matching constructor for initialization of 'span<Base *>'}}
+}
+
+// Similarly, converting a span<int*> to span<const int*> requires internally
+// converting T** to const T**. This is also disallowed, as it would allow code
+// to violate the contract of const.
+void PtrToConstPtrConversionDisallowed() {
+  span<int*> non_const_span;
+  span<const int*> const_span(non_const_span);  // expected-error {{no matching constructor for initialization of 'span<const int *>'}}
+}
+
+// A const container should not be convertible to a mutable span.
+void ConstContainerToMutableConversionDisallowed() {
+  const std::vector<int> v = {1, 2, 3};
+  span<int> span(v);  // expected-error {{no matching constructor for initialization of 'span<int>'}}
+}
+
+// A dynamic const container should not be implicitly convertible to a static span.
+void ImplicitConversionFromDynamicConstContainerToStaticSpanDisallowed() {
+  const std::vector<int> v = {1, 2, 3};
+  span<const int, 3u> span = v;  // expected-error {{no viable conversion from 'const std::vector<int>' to 'span<const int, 3U>'}}
+}
+
+// A dynamic mutable container should not be implicitly convertible to a static span.
+void ImplicitConversionFromDynamicMutableContainerToStaticSpanDisallowed() {
+  std::vector<int> v = {1, 2, 3};
+  span<int, 3u> span = v;  // expected-error {{no viable conversion from 'std::vector<int>' to 'span<int, 3U>'}}
+}
+
+// A std::set() should not satisfy the requirements for conversion to a span.
+void StdSetConversionDisallowed() {
+  std::set<int> set;
+  span<int> span1(set.begin(), 0u);                // expected-error {{no matching constructor for initialization of 'span<int>'}}
+  span<int> span2(set.begin(), set.end());         // expected-error {{no matching constructor for initialization of 'span<int>'}}
+  span<int> span3(set);                            // expected-error {{no matching constructor for initialization of 'span<int>'}}
+  auto span4 = make_span(set.begin(), 0u);         // expected-error@*:* {{no matching constructor for initialization of 'span<T>'}}
+  auto span5 = make_span(set.begin(), set.end());  // expected-error@*:* {{no matching constructor for initialization of 'span<T>'}}
+  auto span6 = make_span(set);                     // expected-error@*:* {{no matching function for call to 'data'}}
+}
+
+// Static views of spans with static extent must not exceed the size.
+void OutOfRangeSubviewsOnStaticSpan() {
+  std::array<int, 3> array = {1, 2, 3};
+  span<int, 3u> span(array);
+  auto first = span.first<4>();          // expected-error@*:* {{Count must not exceed Extent}}
+  auto last = span.last<4>();            // expected-error@*:* {{Count must not exceed Extent}}
+  auto subspan1 = span.subspan<4>();     // expected-error@*:* {{Offset must not exceed Extent}}
+  auto subspan2 = span.subspan<0, 4>();  // expected-error@*:* {{Count must not exceed Extent - Offset}}
+}
+
+// Discarding the return value of empty() is not allowed.
+void DiscardReturnOfEmptyDisallowed() {
+  span<int> s;
+  s.empty();  // expected-error {{ignoring return value of function}}
+}
+
+// Getting elements of an empty span with static extent is not allowed.
+void RefsOnEmptyStaticSpanDisallowed() {
+  span<int, 0u> s;
+  s.front();  // expected-error@*:* {{Extent must not be 0}}
+  s.back();   // expected-error@*:* {{Extent must not be 0}}
+}
+
+// Calling swap on spans with different extents is not allowed.
+void SwapWithDifferentExtentsDisallowed() {
+  std::array<int, 3> array = {1, 2, 3};
+  span<int, 3u> static_span(array);
+  span<int> dynamic_span(array);
+  std::swap(static_span, dynamic_span);  // expected-error {{no matching function for call to 'swap'}}
+}
+
+// as_writable_bytes should not be possible for a const container.
+void AsWritableBytesWithConstContainerDisallowed() {
+  const std::vector<int> v = {1, 2, 3};
+  span<uint8_t> bytes = as_writable_bytes(make_span(v));  // expected-error {{no matching function for call to 'as_writable_bytes'}}
+}
+
+void ConstVectorDeducesAsConstSpan() {
+  const std::vector<int> v;
+  span<int> s = make_span(v);  // expected-error@*:* {{no viable conversion from 'span<T, [...]>' to 'span<int, [...]>'}}
+}
+
+// make_span<N>() should CHECK whether N matches the actual size.
+void MakeSpanChecksSize() {
+  constexpr StringPiece str = "Foo";
+  constexpr auto made_span1 = make_span<2>(str.begin(), 3u);         // expected-error {{constexpr variable 'made_span1' must be initialized by a constant expression}}
+  constexpr auto made_span2 = make_span<2>(str.begin(), str.end());  // expected-error {{constexpr variable 'made_span2' must be initialized by a constant expression}}
+  constexpr auto made_span3 = make_span<2>(str);                     // expected-error {{constexpr variable 'made_span3' must be initialized by a constant expression}}
+}
+
+// EXTENT should not result in |dynamic_extent|, it should be a compile-time
+// error.
+void ExtentNoDynamicExtent() {
+  std::vector<uint8_t> vector;
+  constexpr size_t extent = EXTENT(vector);  // expected-error@*:* {{EXTENT should only be used for containers with a static extent}}
+}
+
+void Dangling() {
+  span<const int, 3u> s1{std::array<int, 3>()};     // expected-error {{object backing the pointer will be destroyed at the end of the full-expression}}
+  span<const int> s2{std::vector<int>({1, 2, 3})};  // expected-error {{object backing the pointer will be destroyed at the end of the full-expression}}
+}
+
+void NotSizeTSize() {
+  std::vector<int> vector = {1, 2, 3};
+  // Using distinct enum types causes distinct span template instantiations, so
+  // we get assertion failures below where we expect.
+  enum Length1 { kSize1 = -1 };
+  enum Length2 { kSize2 = -1 };
+  auto s1 = make_span(vector.data(), kSize1);  // expected-error@*:* {{The source type is out of range for the destination type}}
+  span s2(vector.data(), kSize2);              // expected-error@*:* {{The source type is out of range for the destination type}}
+}
+
+void FromVolatileArrayDisallowed() {
+  static volatile int array[] = {1, 2, 3};
+  span<int> s(array);  // expected-error {{no matching constructor for initialization of 'span<int>'}}
+}
+
+}  // namespace base
diff --git a/base/containers/span_unittest.nc b/base/containers/span_unittest.nc
deleted file mode 100644
index 3c96be2..0000000
--- a/base/containers/span_unittest.nc
+++ /dev/null
@@ -1,311 +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.
-
-// This is a "No Compile Test" suite.
-// http://dev.chromium.org/developers/testing/no-compile-tests
-
-#include "base/containers/span.h"
-
-#include <array>
-#include <set>
-#include <vector>
-
-#include "base/strings/string_piece.h"
-
-namespace base {
-
-class Base {
-};
-
-class Derived : Base {
-};
-
-#if defined(NCTEST_DEFAULT_SPAN_WITH_NON_ZERO_STATIC_EXTENT_DISALLOWED)  // [r"fatal error: static_assert failed due to requirement '1UL == dynamic_extent || 1UL == 0': Invalid Extent"]
-
-// A default constructed span must have an extent of 0 or dynamic_extent.
-void WontCompile() {
-  span<int, 1u> span;
-}
-
-#elif defined(NCTEST_SPAN_FROM_ARRAY_WITH_NON_MATCHING_STATIC_EXTENT_DISALLOWED) // [r"fatal error: no matching constructor for initialization of 'span<int, 1U>'"]
-
-// A span with static extent constructed from an array must match the size of
-// the array.
-void WontCompile() {
-  int array[] = {1, 2, 3};
-  span<int, 1u> span(array);
-}
-
-#elif defined(NCTEST_SPAN_FROM_OTHER_SPAN_WITH_MISMATCHING_EXTENT_DISALLOWED) // [r"fatal error: no matching constructor for initialization of 'span<int, 4U>'"]
-
-// A span with static extent constructed from another span must match the
-// extent.
-void WontCompile() {
-  std::array<int, 3> array = {1, 2, 3};
-  span<int, 3u> span3(array);
-  span<int, 4u> span4(span3);
-}
-
-#elif defined(NCTEST_DYNAMIC_SPAN_TO_STATIC_SPAN_DISALLOWED)  // [r"fatal error: no matching constructor for initialization of 'span<int, 3U>'"]
-
-// Converting a dynamic span to a static span should not be allowed.
-void WontCompile() {
-  span<int> dynamic_span;
-  span<int, 3u> static_span(dynamic_span);
-}
-
-#elif defined(NCTEST_DERIVED_TO_BASE_CONVERSION_DISALLOWED)  // [r"fatal error: no matching constructor for initialization of 'span<Base \*>'"]
-
-// Internally, this is represented as a pointer to pointers to Derived. An
-// implicit conversion to a pointer to pointers to Base must not be allowed.
-// If it were allowed, then something like this would be possible.
-//   Cat** cats = GetCats();
-//   Animals** animals = cats;
-//   animals[0] = new Dog();  // Uhoh!
-void WontCompile() {
-  span<Derived*> derived_span;
-  span<Base*> base_span(derived_span);
-}
-
-#elif defined(NCTEST_PTR_TO_CONSTPTR_CONVERSION_DISALLOWED)  // [r"fatal error: no matching constructor for initialization of 'span<const int \*>'"]
-
-// Similarly, converting a span<int*> to span<const int*> requires internally
-// converting T** to const T**. This is also disallowed, as it would allow code
-// to violate the contract of const.
-void WontCompile() {
-  span<int*> non_const_span;
-  span<const int*> const_span(non_const_span);
-}
-
-#elif defined(NCTEST_CONST_CONTAINER_TO_MUTABLE_CONVERSION_DISALLOWED)  // [r"fatal error: no matching constructor for initialization of 'span<int>'"]
-
-// A const container should not be convertible to a mutable span.
-void WontCompile() {
-  const std::vector<int> v = {1, 2, 3};
-  span<int> span(v);
-}
-
-#elif defined(NCTEST_IMPLICIT_CONVERSION_FROM_DYNAMIC_CONST_CONTAINER_TO_STATIC_SPAN_DISALLOWED) // [r"fatal error: no viable conversion from 'const std::vector<int>' to 'span<const int, 3U>'"]
-
-// A dynamic const container should not be implicitly convertible to a static span.
-void WontCompile() {
-  const std::vector<int> v = {1, 2, 3};
-  span<const int, 3u> span = v;
-}
-
-#elif defined(NCTEST_IMPLICIT_CONVERSION_FROM_DYNAMIC_MUTABLE_CONTAINER_TO_STATIC_SPAN_DISALLOWED) // [r"fatal error: no viable conversion from 'std::vector<int>' to 'span<int, 3U>'"]
-
-// A dynamic mutable container should not be implicitly convertible to a static span.
-void WontCompile() {
-  std::vector<int> v = {1, 2, 3};
-  span<int, 3u> span = v;
-}
-
-#elif defined(NCTEST_STD_SET_ITER_SIZE_CONVERSION_DISALLOWED)  // [r"fatal error: no matching constructor for initialization of 'span<int>'"]
-
-// A std::set() should not satisfy the requirements for conversion to a span.
-void WontCompile() {
-  std::set<int> set;
-  span<int> span(set.begin(), 0u);
-}
-
-#elif defined(NCTEST_STD_SET_ITER_ITER_CONVERSION_DISALLOWED)  // [r"fatal error: no matching constructor for initialization of 'span<int>'"]
-
-// A std::set() should not satisfy the requirements for conversion to a span.
-void WontCompile() {
-  std::set<int> set;
-  span<int> span(set.begin(), set.end());
-}
-
-#elif defined(NCTEST_STD_SET_CONVERSION_DISALLOWED)  // [r"fatal error: no matching constructor for initialization of 'span<int>'"]
-
-// A std::set() should not satisfy the requirements for conversion to a span.
-void WontCompile() {
-  std::set<int> set;
-  span<int> span(set);
-}
-
-#elif defined(NCTEST_STATIC_FRONT_WITH_EXCEEDING_COUNT_DISALLOWED)  // [r" fatal error: static_assert failed due to requirement '3UL == dynamic_extent || 4UL <= 3UL': Count must not exceed Extent"]
-
-// Static first called on a span with static extent must not exceed the size.
-void WontCompile() {
-  std::array<int, 3> array = {1, 2, 3};
-  span<int, 3u> span(array);
-  auto first = span.first<4>();
-}
-
-#elif defined(NCTEST_STATIC_LAST_WITH_EXCEEDING_COUNT_DISALLOWED)  // [r"fatal error: static_assert failed due to requirement '3UL == dynamic_extent || 4UL <= 3UL': Count must not exceed Extent"]
-
-// Static last called on a span with static extent must not exceed the size.
-void WontCompile() {
-  std::array<int, 3> array = {1, 2, 3};
-  span<int, 3u> span(array);
-  auto last = span.last<4>();
-}
-
-#elif defined(NCTEST_STATIC_SUBSPAN_WITH_EXCEEDING_OFFSET_DISALLOWED)  // [r"fatal error: static_assert failed due to requirement '3UL == dynamic_extent || 4UL <= 3UL': Count must not exceed Extent"]
-
-// Static subspan called on a span with static extent must not exceed the size.
-void WontCompile() {
-  std::array<int, 3> array = {1, 2, 3};
-  span<int, 3u> span(array);
-  auto subspan = span.subspan<4>();
-}
-
-#elif defined(NCTEST_STATIC_SUBSPAN_WITH_EXCEEDING_COUNT_DISALLOWED)  // [r"fatal error: static_assert failed due to requirement '3UL == dynamic_extent || 4UL == dynamic_extent || 4UL <= 3UL - 0UL': Count must not exceed Extent - Offset"]
-
-// Static subspan called on a span with static extent must not exceed the size.
-void WontCompile() {
-  std::array<int, 3> array = {1, 2, 3};
-  span<int, 3u> span(array);
-  auto subspan = span.subspan<0, 4>();
-}
-
-#elif defined(NCTEST_DISCARD_RETURN_OF_EMPTY_DISALLOWED) // [r"ignoring return value of function"]
-
-// Discarding the return value of empty() is not allowed.
-void WontCompile() {
-  span<int> s;
-  s.empty();
-}
-
-#elif defined(NCTEST_FRONT_ON_EMPTY_STATIC_SPAN_DISALLOWED) // [r"Extent must not be 0"]
-
-// Front called on an empty span with static extent is not allowed.
-void WontCompile() {
-  span<int, 0u> s;
-  s.front();
-}
-
-#elif defined(NCTEST_BACK_ON_EMPTY_STATIC_SPAN_DISALLOWED) // [r"Extent must not be 0"]
-
-// Back called on an empty span with static extent is not allowed.
-void WontCompile() {
-  span<int, 0u> s;
-  s.back();
-}
-
-#elif defined(NCTEST_SWAP_WITH_DIFFERENT_EXTENTS_DISALLOWED)  // [r"no matching function for call to 'swap'"]
-
-// Calling swap on spans with different extents is not allowed.
-void WontCompile() {
-  std::array<int, 3> array = {1, 2, 3};
-  span<int, 3u> static_span(array);
-  span<int> dynamic_span(array);
-  std::swap(static_span, dynamic_span);
-}
-
-#elif defined(NCTEST_AS_WRITABLE_BYTES_WITH_CONST_CONTAINER_DISALLOWED)  // [r"fatal error: no matching function for call to 'as_writable_bytes'"]
-
-// as_writable_bytes should not be possible for a const container.
-void WontCompile() {
-  const std::vector<int> v = {1, 2, 3};
-  span<uint8_t> bytes = as_writable_bytes(make_span(v));
-}
-
-#elif defined(NCTEST_MAKE_SPAN_FROM_SET_ITER_CONVERSION_DISALLOWED)  // [r"fatal error: no matching constructor for initialization of 'span<T>'"]
-// A std::set() should not satisfy the requirements for conversion to a span.
-void WontCompile() {
-  std::set<int> set;
-  auto span = make_span(set.begin(), set.end());
-}
-
-#elif defined(NCTEST_MAKE_SPAN_FROM_SET_CONVERSION_DISALLOWED)  // [r"fatal error: no matching function for call to 'data'"]
-
-// A std::set() should not satisfy the requirements for conversion to a span.
-void WontCompile() {
-  std::set<int> set;
-  auto span = make_span(set);
-}
-
-#elif defined(NCTEST_CONST_VECTOR_DEDUCES_AS_CONST_SPAN)  // [r"fatal error: no viable conversion from 'span<(T|const int), \[...\]>' to 'span<int, \[...\]>'"]
-
-int WontCompile() {
-  const std::vector<int> v;
-  span<int> s = make_span(v);
-}
-
-#elif defined(NCTEST_STATIC_MAKE_SPAN_FROM_ITER_AND_SIZE_CHECKS)  // [r"constexpr variable 'made_span' must be initialized by a constant expression"]
-
-// The static make_span<N>(begin, size) should CHECK whether N matches size.
-// This should result in compilation failures when evaluated at compile
-// time.
-int WontCompile() {
-  constexpr StringPiece str = "Foo";
-  // Intentional extent mismatch causing CHECK failure.
-  constexpr auto made_span = make_span<2>(str.begin(), 3u);
-}
-
-#elif defined(NCTEST_STATIC_MAKE_SPAN_FROM_ITERS_CHECKS_SIZE)  // [r"constexpr variable 'made_span' must be initialized by a constant expression"]
-
-// The static make_span<N>(begin, end) should CHECK whether N matches end -
-// begin. This should result in compilation failures when evaluated at compile
-// time.
-int WontCompile() {
-  constexpr StringPiece str = "Foo";
-  // Intentional extent mismatch causing CHECK failure.
-  constexpr auto made_span = make_span<2>(str.begin(), str.end());
-}
-
-#elif defined(NCTEST_STATIC_MAKE_SPAN_CHECKS_SIZE)  // [r"constexpr variable 'made_span' must be initialized by a constant expression"]
-
-// The static make_span<N>(cont) should CHECK whether N matches size(cont). This
-// should result in compilation failures when evaluated at compile time.
-int WontCompile() {
-  constexpr StringPiece str = "Foo";
-  // Intentional extent mismatch causing CHECK failure.
-  constexpr auto made_span = make_span<2>(str);
-}
-
-#elif defined(NCTEST_EXTENT_NO_DYNAMIC_EXTENT)  // [r"EXTENT should only be used for containers with a static extent"]
-
-// EXTENT should not result in |dynamic_extent|, it should be a compile-time
-// error.
-void WontCompile() {
-  std::vector<uint8_t> vector;
-  static_assert(EXTENT(vector) == 0, "Should not compile");
-}
-
-#elif defined(NCTEST_DANGLING_STD_ARRAY)  // [r"object backing the pointer will be destroyed at the end of the full-expression"]
-
-void WontCompile() {
-  span<const int, 3u> s{std::array<int, 3>()};
-  (void)s;
-}
-
-#elif defined(NCTEST_DANGLING_CONTAINER)  // [r"object backing the pointer will be destroyed at the end of the full-expression"]
-
-void WontCompile() {
-  span<const int> s{std::vector<int>({1, 2, 3})};
-  (void)s;
-}
-
-#elif defined(NCTEST_MAKE_SPAN_NOT_SIZE_T_SIZE)  // [r"The source type is out of range for the destination type"]
-
-void WontCompile() {
-  int length = -1;
-  std::vector<int> vector = {1, 2, 3};
-  auto s = make_span(vector.data(), length);
-  (void)s;
-}
-
-#elif defined(NCTEST_SPAN_NOT_SIZE_T_SIZE)  // [r"The source type is out of range for the destination type"]
-
-void WontCompile() {
-  int length = -1;
-  std::vector<int> vector = {1, 2, 3};
-  span<int> s(vector.data(), length);
-  (void)s;
-}
-
-#elif defined(NCTEST_SPAN_FROM_VOLATILE_ARRAY_DISALLOWED)  // [r"fatal error: no matching constructor for initialization of 'span<int>'"]
-
-void WontCompile() {
-  static volatile int array[] = {1, 2, 3};
-  span<int> s(array);
-}
-
-#endif
-
-}  // namespace base
diff --git a/base/debug/crash_logging_unittest.nc b/base/debug/crash_logging_nocompile.nc
similarity index 100%
rename from base/debug/crash_logging_unittest.nc
rename to base/debug/crash_logging_nocompile.nc
diff --git a/base/functional/bind_unittest.nc b/base/functional/bind_nocompile.nc
similarity index 100%
rename from base/functional/bind_unittest.nc
rename to base/functional/bind_nocompile.nc
diff --git a/base/functional/callback_unittest.nc b/base/functional/callback_nocompile.nc
similarity index 100%
rename from base/functional/callback_unittest.nc
rename to base/functional/callback_nocompile.nc
diff --git a/base/functional/function_ref_unittest.nc b/base/functional/function_ref_nocompile.nc
similarity index 100%
rename from base/functional/function_ref_unittest.nc
rename to base/functional/function_ref_nocompile.nc
diff --git a/base/functional/overloaded_unittest.nc b/base/functional/overloaded_nocompile.nc
similarity index 100%
rename from base/functional/overloaded_unittest.nc
rename to base/functional/overloaded_nocompile.nc
diff --git a/base/memory/ref_counted_unittest.nc b/base/memory/ref_counted_nocompile.nc
similarity index 100%
rename from base/memory/ref_counted_unittest.nc
rename to base/memory/ref_counted_nocompile.nc
diff --git a/base/metrics/field_trial_params_unittest.nc b/base/metrics/field_trial_params_nocompile.nc
similarity index 100%
rename from base/metrics/field_trial_params_unittest.nc
rename to base/metrics/field_trial_params_nocompile.nc
diff --git a/base/metrics/histogram_unittest.nc b/base/metrics/histogram_nocompile.nc
similarity index 100%
rename from base/metrics/histogram_unittest.nc
rename to base/metrics/histogram_nocompile.nc
diff --git a/base/native_library_unittest.cc b/base/native_library_unittest.cc
index 30ec085b7..22e5d0b 100644
--- a/base/native_library_unittest.cc
+++ b/base/native_library_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "base/native_library.h"
 
+#include "base/check.h"
 #include "base/files/file_path.h"
 #include "base/path_service.h"
 #include "base/test/native_library_test_utils.h"
diff --git a/base/strings/escape.h b/base/strings/escape.h
index 9ada67c..fd0479a 100644
--- a/base/strings/escape.h
+++ b/base/strings/escape.h
@@ -13,6 +13,7 @@
 #include "base/base_export.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/utf_offset_string_conversions.h"
+#include "build/build_config.h"
 
 namespace base {
 
diff --git a/base/strings/string_piece.h b/base/strings/string_piece.h
index 6a8cd34..b5562dec 100644
--- a/base/strings/string_piece.h
+++ b/base/strings/string_piece.h
@@ -10,10 +10,6 @@
 #ifndef BASE_STRINGS_STRING_PIECE_H_
 #define BASE_STRINGS_STRING_PIECE_H_
 
-// Many files including this header rely on these being included due to IWYU
-// violations. Preserve the includes for now. As code is migrated away from this
-// header, we can incrementally fix the IWYU violations.
-#include "base/check.h"
 #include "base/strings/string_piece_forward.h"
 
 #endif  // BASE_STRINGS_STRING_PIECE_H_
diff --git a/base/strings/string_piece_unittest.nc b/base/strings/string_piece_nocompile.nc
similarity index 100%
rename from base/strings/string_piece_unittest.nc
rename to base/strings/string_piece_nocompile.nc
diff --git a/base/traits_bag_unittest.nc b/base/traits_bag_nocompile.nc
similarity index 100%
rename from base/traits_bag_unittest.nc
rename to base/traits_bag_nocompile.nc
diff --git a/base/types/pass_key_unittest.nc b/base/types/pass_key_nocompile.nc
similarity index 100%
rename from base/types/pass_key_unittest.nc
rename to base/types/pass_key_nocompile.nc
diff --git a/base/win/dark_mode_support.cc b/base/win/dark_mode_support.cc
index 325bc70..6b9d2c1 100644
--- a/base/win/dark_mode_support.cc
+++ b/base/win/dark_mode_support.cc
@@ -6,6 +6,7 @@
 
 #include <windows.h>
 
+#include "base/check.h"
 #include "base/native_library.h"
 #include "base/win/windows_version.h"
 
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 80bc79e..f95c417 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -1879,9 +1879,6 @@
 
           # TODO(https://crbug.com/1490607): Fix and re-enable.
           "-Wno-thread-safety-reference-return",
-
-          # TODO(crbug.com/1495100): Evaluate and possibly enable.
-          "-Wno-delayed-template-parsing-in-cxx20",
         ]
       }
     }
diff --git a/buildtools/deps_revisions.gni b/buildtools/deps_revisions.gni
index 6cd927f..88fc17a 100644
--- a/buildtools/deps_revisions.gni
+++ b/buildtools/deps_revisions.gni
@@ -5,5 +5,5 @@
 declare_args() {
   # Used to cause full rebuilds on libc++ rolls. This should be kept in sync
   # with the libcxx_revision vars in //DEPS.
-  libcxx_revision = "d781e6e1b823d1391179f52516e0fc93e61567b2"
+  libcxx_revision = "2364ae8b073e44c9ac2725e176f2ce57967f1012"
 }
diff --git a/buildtools/third_party/libc++/BUILD.gn b/buildtools/third_party/libc++/BUILD.gn
index 04569890c..d17711b 100644
--- a/buildtools/third_party/libc++/BUILD.gn
+++ b/buildtools/third_party/libc++/BUILD.gn
@@ -77,6 +77,7 @@
     "//third_party/libc++/src/src/atomic.cpp",
     "//third_party/libc++/src/src/barrier.cpp",
     "//third_party/libc++/src/src/bind.cpp",
+    "//third_party/libc++/src/src/call_once.cpp",
     "//third_party/libc++/src/src/charconv.cpp",
     "//third_party/libc++/src/src/chrono.cpp",
     "//third_party/libc++/src/src/condition_variable.cpp",
diff --git a/chrome/VERSION b/chrome/VERSION
index 1be427f..a3f3dec5 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=121
 MINOR=0
-BUILD=6113
+BUILD=6114
 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java
index f02b400..b70eda45 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java
@@ -408,12 +408,21 @@
                             mActivityTabProvider,
                             new UserEducationHelper(mActivity, new Handler(Looper.getMainLooper())),
                             mProfileSupplier);
+            Runnable closeTabRunnable =
+                    () -> {
+                        if (mNavigationController.hasValue()) {
+                            mNavigationController.get().navigateOnClose();
+                        }
+                    };
             // The method above already checks for the minimum API level.
             //
             // noinspection NewApi
             mMinimizationManager =
                     new CustomTabMinimizationManager(
-                            mActivity, mActivityTabProvider, mMinimizedCustomTabIPHController);
+                            mActivity,
+                            mActivityTabProvider,
+                            mMinimizedCustomTabIPHController,
+                            closeTabRunnable);
         }
     }
 
@@ -487,6 +496,11 @@
             mPageInsightsCoordinator = null;
         }
 
+        if (mMinimizationManager != null) {
+            mMinimizationManager.destroy();
+            mMinimizationManager = null;
+        }
+
         if (mMinimizedCustomTabIPHController != null) {
             mMinimizedCustomTabIPHController.destroy();
             mMinimizedCustomTabIPHController = null;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/minimizedcustomtab/CustomTabMinimizationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/minimizedcustomtab/CustomTabMinimizationManager.java
index 067733d2..bb5e349 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/minimizedcustomtab/CustomTabMinimizationManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/minimizedcustomtab/CustomTabMinimizationManager.java
@@ -65,21 +65,31 @@
     private final AppCompatActivity mActivity;
     private final ActivityTabProvider mTabProvider;
     private final MinimizedCustomTabFeatureEngagementDelegate mFeatureEngagementDelegate;
+    private final Runnable mCloseTabRunnable;
     private long mMinimizationSystemTime;
 
     /**
      * @param activity The {@link AppCompatActivity} to minimize.
      * @param tabProvider The {@link ActivityTabProvider} that provides the Tab that will be
      *     minimized.
+     * @param featureEngagementDelegate The {@link MinimizedCustomTabFeatureEngagementDelegate}.
+     * @param closeTabRunnable The {@link Runnable} to close the Custom Tab when the minimized tab
+     *     is dismissed.
      */
     public CustomTabMinimizationManager(
             AppCompatActivity activity,
             ActivityTabProvider tabProvider,
-            MinimizedCustomTabFeatureEngagementDelegate featureEngagementDelegate) {
+            MinimizedCustomTabFeatureEngagementDelegate featureEngagementDelegate,
+            Runnable closeTabRunnable) {
         mActivity = activity;
         mActivity.addOnPictureInPictureModeChangedListener(this);
         mTabProvider = tabProvider;
         mFeatureEngagementDelegate = featureEngagementDelegate;
+        mCloseTabRunnable = closeTabRunnable;
+    }
+
+    public void destroy() {
+        mActivity.removeOnPictureInPictureModeChangedListener(this);
     }
 
     /** Minimize the Custom Tab into picture-in-picture. */
@@ -120,6 +130,7 @@
                             TimeUnit.MILLISECONDS.toSeconds(
                                     SystemClock.elapsedRealtime() - mMinimizationSystemTime));
                 }
+                mCloseTabRunnable.run();
                 return;
             }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java
index db8fe626..a7bf334 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java
@@ -16,15 +16,15 @@
 import android.content.pm.ResolveInfo;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
+import android.os.Build;
 import android.os.Parcelable;
+import android.service.chooser.ChooserAction;
 import android.text.TextUtils;
 import android.util.Pair;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.OptIn;
 import androidx.annotation.VisibleForTesting;
-import androidx.core.os.BuildCompat;
 
 import org.chromium.base.ContextUtils;
 import org.chromium.base.IntentUtils;
@@ -40,8 +40,6 @@
 import org.chromium.components.browser_ui.share.ShareParams.TargetChosenCallback;
 import org.chromium.ui.base.WindowAndroid;
 
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -84,7 +82,6 @@
      * @param saveLastUsed True if the chosen share component should be saved for future reuse.
      * @param customActionProvider List of custom actions for Android share sheet.
      */
-    @OptIn(markerClass = BuildCompat.PrereleaseSdkCheck.class)
     public static void shareWithSystemShareSheetUi(ShareParams params, @Nullable Profile profile,
             boolean saveLastUsed, @Nullable ChromeCustomShareAction.Provider customActionProvider) {
         assert (customActionProvider == null || ChooserActionHelper.isSupported())
@@ -290,7 +287,9 @@
         @Override
         protected Intent getChooserIntent(WindowAndroid window, Intent sharingIntent) {
             Intent chooserIntent = super.getChooserIntent(window, sharingIntent);
-            if (mCustomActionProvider == null) return chooserIntent;
+            if (mCustomActionProvider == null || !ChooserActionHelper.isSupported()) {
+                return chooserIntent;
+            }
 
             List<ChromeCustomShareAction> chromeCustomShareActions =
                     mCustomActionProvider.getCustomActions();
@@ -310,7 +309,7 @@
             }
 
             Parcelable[] customActions = chooserActions.toArray(new Parcelable[0]);
-            chooserIntent.putExtra(INTENT_EXTRA_CHOOSER_CUSTOM_ACTIONS, customActions);
+            chooserIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, customActions);
 
             return chooserIntent;
         }
@@ -330,8 +329,12 @@
             sendBackIntent.putExtra(EXTRA_SHARE_CUSTOM_ACTION, action.key);
             // Make custom action immutable, since it doesn't need change any chooser component.
             PendingIntent pendingIntent =
-                    PendingIntent.getBroadcast(activity, requestCode++, sendBackIntent,
-                            PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT
+                    PendingIntent.getBroadcast(
+                            activity,
+                            requestCode,
+                            sendBackIntent,
+                            PendingIntent.FLAG_CANCEL_CURRENT
+                                    | PendingIntent.FLAG_ONE_SHOT
                                     | PendingIntent.FLAG_IMMUTABLE);
 
             Parcelable chooserAction =
@@ -373,38 +376,15 @@
     /**
      * Helper class used to build Android custom action.
      */
-    // TODO(https://crbug.com/1420388): Replace calls with Android OS chooser actions.
     @VisibleForTesting
     public static class ChooserActionHelper {
-        /**
-         * Try to query if the builder class exists.
-         */
-        @SuppressWarnings("PrivateApi")
         static boolean isSupported() {
-            try {
-                Class.forName("android.service.chooser.ChooserAction$Builder");
-                return true;
-            } catch (ClassNotFoundException e) {
-                return false;
-            }
+            return Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
         }
 
-        @SuppressWarnings("PrivateApi")
         static Parcelable newChooserAction(Icon icon, String name, PendingIntent action) {
-            Parcelable parcelable = null;
-            try {
-                Class<?> chooserActionBuilderClass =
-                        Class.forName("android.service.chooser.ChooserAction$Builder");
-                Constructor<?> ctor = chooserActionBuilderClass.getConstructor(
-                        Icon.class, CharSequence.class, PendingIntent.class);
-                Object builder = ctor.newInstance(icon, name, action);
-                parcelable =
-                        (Parcelable) chooserActionBuilderClass.getMethod("build").invoke(builder);
-            } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException
-                    | InvocationTargetException | InstantiationException e) {
-                Log.w(TAG, "Building ChooserAction failed.", e);
-            }
-            return parcelable;
+            if (!isSupported()) return null;
+            return new ChooserAction.Builder(icon, name, action).build();
         }
     }
 }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/features/minimizedcustomtab/CustomTabMinimizationManagerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/features/minimizedcustomtab/CustomTabMinimizationManagerUnitTest.java
index 54d6890..a223fb7 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/features/minimizedcustomtab/CustomTabMinimizationManagerUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/features/minimizedcustomtab/CustomTabMinimizationManagerUnitTest.java
@@ -74,6 +74,7 @@
     @Mock private Tab mTab;
     @Mock private WebContents mWebContents;
     @Mock private MinimizedCustomTabFeatureEngagementDelegate mFeatureEngagementDelegate;
+    @Mock private Runnable mCloseTabRunnable;
 
     private CustomTabMinimizationManager mManager;
 
@@ -90,7 +91,7 @@
                 .thenReturn(true);
         mManager =
                 new CustomTabMinimizationManager(
-                        mActivity, mTabProvider, mFeatureEngagementDelegate);
+                        mActivity, mTabProvider, mFeatureEngagementDelegate, mCloseTabRunnable);
     }
 
     @Test
@@ -158,6 +159,7 @@
         mManager.accept(new PictureInPictureModeChangedInfo(false));
 
         verify(mTab, never()).show(anyInt(), anyInt());
+        verify(mCloseTabRunnable).run();
 
         minimizationEventsWatcher.assertExpected(
                 "CustomTabs.MinimizedEvents.DESTROY should be recorded once");
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/share/ShareHelperUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/share/ShareHelperUnitTest.java
index e00a705..48c0571 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/share/ShareHelperUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/share/ShareHelperUnitTest.java
@@ -22,8 +22,6 @@
 import android.os.Looper;
 import android.os.Parcelable;
 
-import androidx.core.os.BuildCompat;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -268,7 +266,7 @@
     }
 
     @Test
-    @Config(shadows = {ShadowBuildCompatForU.class, ShadowChooserActionHelper.class})
+    @Config(shadows = {ShadowChooserActionHelper.class})
     public void shareWithCustomActions() throws SendIntentException {
         String actionKey = "key";
         CallbackHelper callbackHelper = new CallbackHelper();
@@ -399,16 +397,6 @@
         }
     }
 
-    // Work around shadow to assume runtime is at least U.
-    // TODO(https://crbug.com/1420388): Switch to @Config(sdk=34) this once API 34 exists.
-    @Implements(BuildCompat.class)
-    static class ShadowBuildCompatForU {
-        @Implementation
-        protected static boolean isAtLeastU() {
-            return true;
-        }
-    }
-
     /** Test implementation to build a ChooserAction. */
     @Implements(ShareHelper.ChooserActionHelper.class)
     static class ShadowChooserActionHelper {
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 705046ac..12f33bd 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -7850,6 +7850,12 @@
       <message name="IDS_NTP_WALLPAPER_SEARCH_HISTORY_HEADER" translateable="false" desc="Header for the wallpaper search section for showing past themes." >
         Your recent themes
       </message>
+      <message name="IDS_NTP_WALLPAPER_SEARCH_OFFLINE_DESCRIPTION" desc="The description of the message displayed by wallpaper search when the browser is offline.">
+        Check your internet connection and try again.
+      </message>
+      <message name="IDS_NTP_WALLPAPER_SEARCH_OFFLINE_TITLE" desc="The title of the message displayed by wallpaper search when the browser is offline.">
+        Looks like you're offline.
+      </message>
       <message name="IDS_NTP_WALLPAPER_SEARCH_REQUEST_THROTTLED_DESCRIPTION" desc="The description of the message displayed when a wallpaper search request is throttled.">
         You can try again tomorrow.
       </message>
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_WALLPAPER_SEARCH_OFFLINE_DESCRIPTION.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_WALLPAPER_SEARCH_OFFLINE_DESCRIPTION.png.sha1
new file mode 100644
index 0000000..3ff2186
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_NTP_WALLPAPER_SEARCH_OFFLINE_DESCRIPTION.png.sha1
@@ -0,0 +1 @@
+0b30554793a1373c4417efd8c0f61adbd36ac6ea
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_WALLPAPER_SEARCH_OFFLINE_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_WALLPAPER_SEARCH_OFFLINE_TITLE.png.sha1
new file mode 100644
index 0000000..3ff2186
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_NTP_WALLPAPER_SEARCH_OFFLINE_TITLE.png.sha1
@@ -0,0 +1 @@
+0b30554793a1373c4417efd8c0f61adbd36ac6ea
\ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 8be0ce7..8bad7bf 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -3036,6 +3036,8 @@
     "wallpaper-google-photos-shared-albums";
 constexpr char kWallpaperPerDeskName[] = "per-desk-wallpaper";
 constexpr char kTimeOfDayWallpaperInternalName[] = "time-of-day-wallpaper";
+constexpr char kTimeOfDayWallpaperForcedAutoScheduleInternalName[] =
+    "time-of-day-wallpaper-forced-auto-schedule";
 constexpr char kTimeOfDayScreenSaverInternalName[] = "time-of-day-screen-saver";
 constexpr char kTimeOfDayDlcInternalName[] = "time-of-day-dlc";
 constexpr char kGlanceablesV2InternalName[] = "glanceables-v2";
@@ -4357,9 +4359,6 @@
     {"bluetooth-quality-report", flag_descriptions::kBluetoothQualityReportName,
      flag_descriptions::kBluetoothQualityReportDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(ash::features::kBluetoothQualityReport)},
-    {"bluetooth-wbs-dogfood", flag_descriptions::kBluetoothWbsDogfoodName,
-     flag_descriptions::kBluetoothWbsDogfoodDescription, kOsCrOS,
-     FEATURE_VALUE_TYPE(ash::features::kBluetoothWbsDogfood)},
     {"bluetooth-coredump", flag_descriptions::kBluetoothCoredumpName,
      flag_descriptions::kBluetoothCoredumpDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(chromeos::bluetooth::features::kBluetoothCoredump)},
@@ -4622,6 +4621,11 @@
      flag_descriptions::kTimeOfDayWallpaperName,
      flag_descriptions::kTimeOfDayWallpaperDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(ash::features::kTimeOfDayWallpaper)},
+    {kTimeOfDayWallpaperForcedAutoScheduleInternalName,
+     flag_descriptions::kTimeOfDayWallpaperForcedAutoScheduleName,
+     flag_descriptions::kTimeOfDayWallpaperForcedAutoScheduleDescription,
+     kOsCrOS,
+     FEATURE_VALUE_TYPE(ash::features::kTimeOfDayWallpaperForcedAutoSchedule)},
     {kTimeOfDayDlcInternalName, flag_descriptions::kTimeOfDayDlcName,
      flag_descriptions::kTimeOfDayDlcDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(ash::features::kTimeOfDayDlc)},
@@ -9616,20 +9620,20 @@
 #endif
 
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || \
-    BUILDFLAG(IS_CHROMEOS_ASH)
+    BUILDFLAG(IS_CHROMEOS)
     {"document-picture-in-picture-api",
      flag_descriptions::kDocumentPictureInPictureApiName,
      flag_descriptions::kDocumentPictureInPictureApiDescription,
-     kOsMac | kOsWin | kOsLinux | kOsCrOS,
+     kOsMac | kOsWin | kOsLinux | kOsCrOS | kOsLacros,
      FEATURE_VALUE_TYPE(blink::features::kDocumentPictureInPictureAPI)},
 
     {"media-session-enter-picture-in-picture",
      flag_descriptions::kMediaSessionEnterPictureInPictureName,
      flag_descriptions::kMediaSessionEnterPictureInPictureDescription,
-     kOsMac | kOsWin | kOsLinux | kOsCrOS,
+     kOsMac | kOsWin | kOsLinux | kOsCrOS | kOsLacros,
      FEATURE_VALUE_TYPE(blink::features::kMediaSessionEnterPictureInPicture)},
 #endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) ||
-        // BUILDFLAG(IS_CHROMEOS_ASH)
+        // BUILDFLAG(IS_CHROMEOS)
 
     {"web-midi", flag_descriptions::kWebMidiName,
      flag_descriptions::kWebMidiDescription, kOsAll,
diff --git a/chrome/browser/apps/app_service/publishers/publisher_unittest.cc b/chrome/browser/apps/app_service/publishers/publisher_unittest.cc
index 6f7e9b68..689d819 100644
--- a/chrome/browser/apps/app_service/publishers/publisher_unittest.cc
+++ b/chrome/browser/apps/app_service/publishers/publisher_unittest.cc
@@ -52,12 +52,14 @@
 #include "chrome/browser/ash/crosapi/fake_browser_manager.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/common/chrome_features.h"
+#include "chrome/grit/branded_strings.h"
 #include "chromeos/ash/components/login/login_state/login_state.h"
 #include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #include "chromeos/ash/components/standalone_browser/standalone_browser_features.h"
 #include "components/services/app_service/public/cpp/app_capability_access_cache.h"
 #include "components/services/app_service/public/cpp/capability_access_update.h"
 #include "components/user_manager/scoped_user_manager.h"
+#include "ui/base/l10n/l10n_util.h"
 
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
@@ -812,9 +814,11 @@
 };
 
 TEST_F(StandaloneBrowserPublisherTest, StandaloneBrowserAppsOnApps) {
-  VerifyApp(AppType::kStandaloneBrowser, app_constants::kLacrosAppId, "Chrome",
-            Readiness::kReady, InstallReason::kSystem, InstallSource::kSystem,
-            {}, base::Time(), base::Time(), apps::Permissions(),
+  std::string lacros_app_name = l10n_util::GetStringUTF8(IDS_PRODUCT_NAME);
+  VerifyApp(AppType::kStandaloneBrowser, app_constants::kLacrosAppId,
+            lacros_app_name, Readiness::kReady, InstallReason::kSystem,
+            InstallSource::kSystem, {}, base::Time(), base::Time(),
+            apps::Permissions(),
             /*is_platform_app=*/false,
             /*recommendable=*/true, /*searchable=*/true,
             /*show_in_launcher=*/true, /*show_in_shelf=*/true,
diff --git a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc
index 8a81891..37ed1bdd 100644
--- a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc
+++ b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc
@@ -19,9 +19,11 @@
 #include "chrome/browser/web_applications/web_app_utils.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/webui_url_constants.h"
+#include "chrome/grit/branded_strings.h"
 #include "chrome/grit/chrome_unscaled_resources.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/app_constants/constants.h"
+#include "ui/base/l10n/l10n_util.h"
 #include "ui/views/widget/widget.h"
 
 namespace {
@@ -50,12 +52,6 @@
   return icon_key;
 }
 
-std::string GetStandaloneBrowserName() {
-  // "Chrome" is hard-coded to be consistent with
-  // chrome/browser/resources/chrome_app/manifest.json.
-  return crosapi::browser_util::IsAshWebBrowserEnabled() ? "Lacros" : "Chrome";
-}
-
 }  // namespace
 
 namespace apps {
@@ -80,10 +76,20 @@
 }
 
 AppPtr StandaloneBrowserApps::CreateStandaloneBrowserApp() {
+  std::string full_name;
+  std::string short_name;
+  if (crosapi::browser_util::IsAshWebBrowserEnabled()) {
+    full_name = short_name = "Lacros";
+  } else {
+    full_name = l10n_util::GetStringUTF8(IDS_PRODUCT_NAME);
+    short_name = l10n_util::GetStringUTF8(IDS_SHORT_PRODUCT_NAME);
+  }
+
   auto app = apps::AppPublisher::MakeApp(
       AppType::kStandaloneBrowser, app_constants::kLacrosAppId,
-      Readiness::kReady, GetStandaloneBrowserName(), InstallReason::kSystem,
+      Readiness::kReady, full_name, InstallReason::kSystem,
       InstallSource::kSystem);
+  app->short_name = short_name;
 
   if (crosapi::browser_util::IsAshWebBrowserEnabled())
     app->additional_search_terms.push_back("chrome");
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn
index 203be8a..ff7e0ec 100644
--- a/chrome/browser/ash/BUILD.gn
+++ b/chrome/browser/ash/BUILD.gn
@@ -1323,6 +1323,8 @@
     "fileapi/fallback_copy_in_foreign_file.h",
     "fileapi/file_access_permissions.cc",
     "fileapi/file_access_permissions.h",
+    "fileapi/file_accumulator.cc",
+    "fileapi/file_accumulator.h",
     "fileapi/file_change_service.cc",
     "fileapi/file_change_service.h",
     "fileapi/file_change_service_factory.cc",
@@ -1877,8 +1879,6 @@
     "login/screens/lacros_data_backward_migration_screen.h",
     "login/screens/lacros_data_migration_screen.cc",
     "login/screens/lacros_data_migration_screen.h",
-    "login/screens/local_password_setup_screen.cc",
-    "login/screens/local_password_setup_screen.h",
     "login/screens/local_state_error_screen.cc",
     "login/screens/local_state_error_screen.h",
     "login/screens/locale_switch_notification.cc",
@@ -1903,6 +1903,10 @@
     "login/screens/os_install_screen.h",
     "login/screens/os_trial_screen.cc",
     "login/screens/os_trial_screen.h",
+    "login/screens/osauth/base_osauth_setup_screen.cc",
+    "login/screens/osauth/base_osauth_setup_screen.h",
+    "login/screens/osauth/local_password_setup_screen.cc",
+    "login/screens/osauth/local_password_setup_screen.h",
     "login/screens/packaged_license_screen.cc",
     "login/screens/packaged_license_screen.h",
     "login/screens/parental_handoff_screen.cc",
@@ -5438,6 +5442,7 @@
     "fileapi/external_file_url_util_unittest.cc",
     "fileapi/fallback_copy_in_foreign_file_unittest.cc",
     "fileapi/file_access_permissions_unittest.cc",
+    "fileapi/file_accumulator_unittest.cc",
     "fileapi/file_change_service_unittest.cc",
     "fileapi/file_system_backend_unittest.cc",
     "fileapi/recent_arc_media_source_unittest.cc",
diff --git a/chrome/browser/ash/app_list/app_service/app_service_app_icon_loader.cc b/chrome/browser/ash/app_list/app_service/app_service_app_icon_loader.cc
index 41d4c179..d9f10af5 100644
--- a/chrome/browser/ash/app_list/app_service/app_service_app_icon_loader.cc
+++ b/chrome/browser/ash/app_list/app_service/app_service_app_icon_loader.cc
@@ -82,6 +82,7 @@
   if (it != icon_map_.end()) {
     if (!it->second.isNull()) {
       delegate()->OnAppImageUpdated(id, it->second,
+                                    /*is_placeholder_icon=*/false,
                                     /*badge_image=*/absl::nullopt);
     }
     return;
@@ -111,7 +112,9 @@
     return;
   }
 
-  delegate()->OnAppImageUpdated(id, it->second, /*badge_image=*/absl::nullopt);
+  delegate()->OnAppImageUpdated(id, it->second,
+                                /*is_placeholder_icon=*/false,
+                                /*badge_image=*/absl::nullopt);
 }
 
 void AppServiceAppIconLoader::OnAppUpdate(const apps::AppUpdate& update) {
@@ -180,7 +183,8 @@
     }
     gfx::ImageSkia image = icon_value->uncompressed;
     icon_map_[id] = image;
-    delegate()->OnAppImageUpdated(id, image, /*badge_image=*/absl::nullopt);
+    delegate()->OnAppImageUpdated(id, image, icon_value->is_placeholder_icon,
+                                  /*badge_image=*/absl::nullopt);
   }
 
   if (icon_value->is_placeholder_icon) {
diff --git a/chrome/browser/ash/app_list/app_service/app_service_promise_app_icon_loader.cc b/chrome/browser/ash/app_list/app_service/app_service_promise_app_icon_loader.cc
index 149301e..66e51125 100644
--- a/chrome/browser/ash/app_list/app_service/app_service_promise_app_icon_loader.cc
+++ b/chrome/browser/ash/app_list/app_service/app_service_promise_app_icon_loader.cc
@@ -106,5 +106,6 @@
     apps::IconValuePtr icon_value) {
   gfx::ImageSkia image = icon_value->uncompressed;
   delegate()->OnAppImageUpdated(package_id.ToString(), image,
+                                icon_value->is_placeholder_icon,
                                 /*badge_image=*/absl::nullopt);
 }
diff --git a/chrome/browser/ash/app_list/app_service/app_service_shortcut_icon_loader.cc b/chrome/browser/ash/app_list/app_service/app_service_shortcut_icon_loader.cc
index e8798a51..754073f 100644
--- a/chrome/browser/ash/app_list/app_service/app_service_shortcut_icon_loader.cc
+++ b/chrome/browser/ash/app_list/app_service/app_service_shortcut_icon_loader.cc
@@ -52,7 +52,9 @@
   ShortcutIDToIconMap::const_iterator it = icon_map_.find(id);
   if (it != icon_map_.end()) {
     if (!it->second.image.isNull()) {
-      delegate()->OnAppImageUpdated(id, it->second.image, it->second.badge);
+      delegate()->OnAppImageUpdated(id, it->second.image,
+                                    /*is_placeholder_icon=*/false,
+                                    it->second.badge);
     }
     return;
   }
@@ -71,7 +73,9 @@
     return;
   }
 
-  delegate()->OnAppImageUpdated(id, it->second.image, it->second.badge);
+  delegate()->OnAppImageUpdated(id, it->second.image,
+                                /*is_placeholder_icon=*/false,
+                                it->second.badge);
 }
 
 void AppServiceShortcutIconLoader::OnShortcutUpdated(
@@ -121,5 +125,6 @@
           : gfx::ImageSkia();
 
   icon_map_[shortcut_id.value()] = {.image = image, .badge = badge};
-  delegate()->OnAppImageUpdated(shortcut_id.value(), image, badge);
+  delegate()->OnAppImageUpdated(shortcut_id.value(), image,
+                                /*is_placeholder_icon=*/false, badge);
 }
diff --git a/chrome/browser/ash/app_list/arc/arc_app_unittest.cc b/chrome/browser/ash/app_list/arc/arc_app_unittest.cc
index 14a4987..6673d63f 100644
--- a/chrome/browser/ash/app_list/arc/arc_app_unittest.cc
+++ b/chrome/browser/ash/app_list/arc/arc_app_unittest.cc
@@ -171,6 +171,7 @@
   void OnAppImageUpdated(
       const std::string& app_id,
       const gfx::ImageSkia& image,
+      bool is_placeholder_icon,
       const absl::optional<gfx::ImageSkia>& badge_image) override {
     app_id_ = app_id;
     image_ = image;
diff --git a/chrome/browser/ash/app_list/launcher_search_iph_browsertest.cc b/chrome/browser/ash/app_list/launcher_search_iph_browsertest.cc
index 346c1c0..d7311818 100644
--- a/chrome/browser/ash/app_list/launcher_search_iph_browsertest.cc
+++ b/chrome/browser/ash/app_list/launcher_search_iph_browsertest.cc
@@ -353,7 +353,9 @@
   EXPECT_FALSE(IsLauncherSearchIphViewVisible());
 }
 
-IN_PROC_BROWSER_TEST_P(AppListIphBrowserTestWithTestConfig, ClickChip) {
+// TODO(crbug.com/1500165): Consistently failing - fix and re-enable.
+IN_PROC_BROWSER_TEST_P(AppListIphBrowserTestWithTestConfig,
+                       DISABLED_ClickChip) {
   OpenAppListAndWaitForIphView();
 
   // Chip click is specified as EventUsed in the test config.
diff --git a/chrome/browser/ash/app_list/search/arc/arc_app_shortcut_search_result.cc b/chrome/browser/ash/app_list/search/arc/arc_app_shortcut_search_result.cc
index 4a5ed8d..73a66c4 100644
--- a/chrome/browser/ash/app_list/search/arc/arc_app_shortcut_search_result.cc
+++ b/chrome/browser/ash/app_list/search/arc/arc_app_shortcut_search_result.cc
@@ -112,6 +112,7 @@
 void ArcAppShortcutSearchResult::OnAppImageUpdated(
     const std::string& app_id,
     const gfx::ImageSkia& image,
+    bool is_placeholder_icon,
     const absl::optional<gfx::ImageSkia>& badge_image) {
   SetBadgeIcon(ui::ImageModel::FromImageSkia(image));
 }
diff --git a/chrome/browser/ash/app_list/search/arc/arc_app_shortcut_search_result.h b/chrome/browser/ash/app_list/search/arc/arc_app_shortcut_search_result.h
index fe1d7ae..40ddc18b 100644
--- a/chrome/browser/ash/app_list/search/arc/arc_app_shortcut_search_result.h
+++ b/chrome/browser/ash/app_list/search/arc/arc_app_shortcut_search_result.h
@@ -56,6 +56,7 @@
   void OnAppImageUpdated(
       const std::string& app_id,
       const gfx::ImageSkia& image,
+      bool is_placeholder_icon,
       const absl::optional<gfx::ImageSkia>& badge_image) override;
 
   // Gets app id of the app that publishes this app shortcut.
diff --git a/chrome/browser/ash/arc/fileapi/arc_documents_provider_root.cc b/chrome/browser/ash/arc/fileapi/arc_documents_provider_root.cc
index b359176..4da73b0 100644
--- a/chrome/browser/ash/arc/fileapi/arc_documents_provider_root.cc
+++ b/chrome/browser/ash/arc/fileapi/arc_documents_provider_root.cc
@@ -172,9 +172,9 @@
     return;
   }
   ResolveToDocumentId(
-      path,
-      base::BindOnce(&ArcDocumentsProviderRoot::DeleteFileWithDocumentId,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+      path, base::BindOnce(&ArcDocumentsProviderRoot::DeleteFileWithDocumentId,
+                           weak_ptr_factory_.GetWeakPtr(), std::move(callback),
+                           path));
 }
 
 void ArcDocumentsProviderRoot::CreateFile(const base::FilePath& path,
@@ -435,7 +435,19 @@
 
 void ArcDocumentsProviderRoot::DeleteFileWithDocumentId(
     StatusCallback callback,
+    const base::FilePath& path,
     const std::string& document_id) {
+  ResolveToDocumentId(
+      path.DirName(),
+      base::BindOnce(&ArcDocumentsProviderRoot::DeleteFileWithParentDocumentId,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback),
+                     document_id));
+}
+
+void ArcDocumentsProviderRoot::DeleteFileWithParentDocumentId(
+    StatusCallback callback,
+    const std::string& document_id,
+    const std::string& parent_document_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (document_id.empty()) {
     std::move(callback).Run(base::File::FILE_ERROR_NOT_FOUND);
@@ -445,12 +457,18 @@
   runner_->DeleteDocument(
       authority_, document_id,
       base::BindOnce(&ArcDocumentsProviderRoot::OnFileDeleted,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback),
+                     parent_document_id));
 }
 
-void ArcDocumentsProviderRoot::OnFileDeleted(StatusCallback callback,
-                                             bool success) {
+void ArcDocumentsProviderRoot::OnFileDeleted(
+    StatusCallback callback,
+    const std::string& parent_document_id,
+    bool success) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  if (success) {
+    ClearDirectoryCache(parent_document_id);
+  }
   std::move(callback).Run(success ? base::File::FILE_OK
                                   : base::File::FILE_ERROR_FAILED);
 }
@@ -546,13 +564,26 @@
   ResolveToDocumentId(
       path, base::BindOnce(&ArcDocumentsProviderRoot::RenameFileWithDocumentId,
                            weak_ptr_factory_.GetWeakPtr(), std::move(callback),
-                           display_name));
+                           path, display_name));
 }
 
 void ArcDocumentsProviderRoot::RenameFileWithDocumentId(
     StatusCallback callback,
+    const base::FilePath& path,
     const std::string& display_name,
     const std::string& document_id) {
+  ResolveToDocumentId(
+      path.DirName(),
+      base::BindOnce(&ArcDocumentsProviderRoot::RenameFileWithParentDocumentId,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback),
+                     display_name, document_id));
+}
+
+void ArcDocumentsProviderRoot::RenameFileWithParentDocumentId(
+    StatusCallback callback,
+    const std::string& display_name,
+    const std::string& document_id,
+    const std::string& parent_document_id) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (document_id.empty()) {
     std::move(callback).Run(base::File::FILE_ERROR_NOT_FOUND);
@@ -563,16 +594,23 @@
   runner_->RenameDocument(
       authority_, document_id, display_name,
       base::BindOnce(&ArcDocumentsProviderRoot::OnFileRenamed,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback),
+                     parent_document_id));
 }
 
-void ArcDocumentsProviderRoot::OnFileRenamed(StatusCallback callback,
-                                             mojom::DocumentPtr document) {
+void ArcDocumentsProviderRoot::OnFileRenamed(
+    StatusCallback callback,
+    const std::string& parent_document_id,
+    mojom::DocumentPtr document) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (document.is_null()) {
     std::move(callback).Run(base::File::FILE_ERROR_FAILED);
     return;
   }
+
+  if (!parent_document_id.empty()) {
+    ClearDirectoryCache(parent_document_id);
+  }
   std::move(callback).Run(base::File::FILE_OK);
 }
 
@@ -611,12 +649,13 @@
       authority_, source_document_id, target_parent_document_id,
       base::BindOnce(&ArcDocumentsProviderRoot::OnFileCopied,
                      weak_ptr_factory_.GetWeakPtr(), std::move(callback),
-                     target_display_name_to_rename));
+                     target_display_name_to_rename, target_parent_document_id));
 }
 
 void ArcDocumentsProviderRoot::OnFileCopied(
     StatusCallback callback,
     const std::string& target_display_name_to_rename,
+    const std::string& target_parent_document_id,
     mojom::DocumentPtr document) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (document.is_null()) {
@@ -624,11 +663,13 @@
     return;
   }
   if (target_display_name_to_rename.empty()) {
+    ClearDirectoryCache(target_parent_document_id);
     std::move(callback).Run(base::File::FILE_OK);
     return;
   }
-  RenameFileWithDocumentId(std::move(callback), target_display_name_to_rename,
-                           document->document_id);
+  RenameFileWithParentDocumentId(
+      std::move(callback), target_display_name_to_rename, document->document_id,
+      target_parent_document_id);
 }
 
 void ArcDocumentsProviderRoot::MoveFileInternal(
@@ -702,24 +743,31 @@
       target_parent_document_id,
       base::BindOnce(&ArcDocumentsProviderRoot::OnFileMoved,
                      weak_ptr_factory_.GetWeakPtr(), std::move(callback),
-                     target_display_name_to_rename));
+                     target_display_name_to_rename, source_parent_document_id,
+                     target_parent_document_id));
 }
 
 void ArcDocumentsProviderRoot::OnFileMoved(
     StatusCallback callback,
     const std::string& target_display_name_to_rename,
+    const std::string& source_parent_document_id,
+    const std::string& target_parent_document_id,
     mojom::DocumentPtr document) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   if (document.is_null()) {
     std::move(callback).Run(base::File::FILE_ERROR_FAILED);
     return;
   }
+  ClearDirectoryCache(source_parent_document_id);
+
   if (target_display_name_to_rename.empty()) {
+    ClearDirectoryCache(target_parent_document_id);
     std::move(callback).Run(base::File::FILE_OK);
     return;
   }
-  RenameFileWithDocumentId(std::move(callback), target_display_name_to_rename,
-                           document->document_id);
+  RenameFileWithParentDocumentId(
+      std::move(callback), target_display_name_to_rename, document->document_id,
+      target_parent_document_id);
 }
 
 void ArcDocumentsProviderRoot::AddWatcherWithDocumentId(
diff --git a/chrome/browser/ash/arc/fileapi/arc_documents_provider_root.h b/chrome/browser/ash/arc/fileapi/arc_documents_provider_root.h
index 48a76c4..b7e8e64 100644
--- a/chrome/browser/ash/arc/fileapi/arc_documents_provider_root.h
+++ b/chrome/browser/ash/arc/fileapi/arc_documents_provider_root.h
@@ -261,8 +261,14 @@
                                           const NameToDocumentMap& mapping);
 
   void DeleteFileWithDocumentId(StatusCallback callback,
+                                const base::FilePath& path,
                                 const std::string& document_id);
-  void OnFileDeleted(StatusCallback callback, bool success);
+  void DeleteFileWithParentDocumentId(StatusCallback callback,
+                                      const std::string& document_id,
+                                      const std::string& parent_document_id);
+  void OnFileDeleted(StatusCallback callback,
+                     const std::string& parent_document_id,
+                     bool success);
 
   void CreateFileAfterConflictCheck(StatusCallback callback,
                                     const base::FilePath& path,
@@ -286,9 +292,16 @@
                           const std::string& display_name,
                           StatusCallback callback);
   void RenameFileWithDocumentId(StatusCallback callback,
+                                const base::FilePath& path,
                                 const std::string& display_name,
-                                const std::string& documentId);
-  void OnFileRenamed(StatusCallback callback, mojom::DocumentPtr document);
+                                const std::string& document_id);
+  void RenameFileWithParentDocumentId(StatusCallback callback,
+                                      const std::string& display_name,
+                                      const std::string& document_id,
+                                      const std::string& parent_document_id);
+  void OnFileRenamed(StatusCallback callback,
+                     const std::string& parent_document_id,
+                     mojom::DocumentPtr document);
 
   void CopyFileWithSourceDocumentId(StatusCallback callback,
                                     const base::FilePath& target_path,
@@ -301,6 +314,7 @@
       const std::string& target_parent_document_id);
   void OnFileCopied(StatusCallback callback,
                     const std::string& target_display_name_to_rename,
+                    const std::string& target_parent_document_id,
                     mojom::DocumentPtr document);
 
   void MoveFileInternal(const base::FilePath& source_path,
@@ -325,6 +339,8 @@
       const std::string& target_parent_document_id);
   void OnFileMoved(StatusCallback callback,
                    const std::string& target_display_name_to_rename,
+                   const std::string& source_parent_document_id,
+                   const std::string& target_parent_document_id,
                    mojom::DocumentPtr document);
 
   void AddWatcherWithDocumentId(const base::FilePath& path,
diff --git a/chrome/browser/ash/arc/fileapi/arc_documents_provider_root_unittest.cc b/chrome/browser/ash/arc/fileapi/arc_documents_provider_root_unittest.cc
index f74494a..82460134 100644
--- a/chrome/browser/ash/arc/fileapi/arc_documents_provider_root_unittest.cc
+++ b/chrome/browser/ash/arc/fileapi/arc_documents_provider_root_unittest.cc
@@ -778,6 +778,38 @@
       base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg"))));
 }
 
+TEST_F(ArcDocumentsProviderRootTest, DeleteFileThenGetMetadataClearsCache) {
+  // Make sure that dir/photo.jpg exists.
+  ASSERT_TRUE(fake_file_system_.DocumentExists(
+      kAuthority, kRootSpec.document_id,
+      base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg"))));
+
+  base::RunLoop run_loop;
+  root_->DeleteFile(base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg")),
+                    base::BindOnce(
+                        [](base::RunLoop* run_loop, base::File::Error error) {
+                          run_loop->Quit();
+                          EXPECT_EQ(base::File::FILE_OK, error);
+                        },
+                        &run_loop));
+  run_loop.Run();
+
+  // dir/photo.jpg should have been removed.
+  {
+    base::RunLoop run_loop;
+    root_->GetExtraFileMetadata(
+        base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg")),
+        base::BindOnce(
+            [](base::RunLoop* run_loop, base::File::Error error,
+               const ArcDocumentsProviderRoot::ExtraFileMetadata& metadata) {
+              run_loop->Quit();
+              EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, error);
+            },
+            &run_loop));
+    run_loop.Run();
+  }
+}
+
 TEST_F(ArcDocumentsProviderRootTest, DeleteFileNonExist) {
   base::RunLoop run_loop;
   root_->DeleteFile(base::FilePath(FILE_PATH_LITERAL("dir/non_exist.jpg")),
@@ -1103,6 +1135,50 @@
       base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg"))));
 }
 
+TEST_F(ArcDocumentsProviderRootTest, CopyFileThenGetMetadataClearsCache) {
+  base::RunLoop run_loop;
+  root_->CopyFileLocal(
+      base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg")),
+      base::FilePath(FILE_PATH_LITERAL("dir/photo2.jpg")),
+      base::BindOnce(
+          [](base::RunLoop* run_loop, base::File::Error error) {
+            run_loop->Quit();
+            EXPECT_EQ(base::File::FILE_OK, error);
+          },
+          &run_loop));
+  run_loop.Run();
+
+  // dir/photo2.jpg should be created by the copy.
+  {
+    base::RunLoop run_loop;
+    root_->GetExtraFileMetadata(
+        base::FilePath(FILE_PATH_LITERAL("dir/photo2.jpg")),
+        base::BindOnce(
+            [](base::RunLoop* run_loop, base::File::Error error,
+               const ArcDocumentsProviderRoot::ExtraFileMetadata& metadata) {
+              run_loop->Quit();
+              EXPECT_EQ(base::File::FILE_OK, error);
+            },
+            &run_loop));
+    run_loop.Run();
+  }
+
+  // The source file should still be there.
+  {
+    base::RunLoop run_loop;
+    root_->GetExtraFileMetadata(
+        base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg")),
+        base::BindOnce(
+            [](base::RunLoop* run_loop, base::File::Error error,
+               const ArcDocumentsProviderRoot::ExtraFileMetadata& metadata) {
+              run_loop->Quit();
+              EXPECT_EQ(base::File::FILE_OK, error);
+            },
+            &run_loop));
+    run_loop.Run();
+  }
+}
+
 TEST_F(ArcDocumentsProviderRootTest, CopyFileToDifferentDirectory) {
   base::RunLoop run_loop;
   root_->CopyFileLocal(
@@ -1206,6 +1282,50 @@
           .document_id);
 }
 
+TEST_F(ArcDocumentsProviderRootTest, RenameFileThenGetMetadataClearsCache) {
+  base::RunLoop run_loop;
+  root_->MoveFileLocal(
+      base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg")),
+      base::FilePath(FILE_PATH_LITERAL("dir/photo2.jpg")),
+      base::BindOnce(
+          [](base::RunLoop* run_loop, base::File::Error error) {
+            run_loop->Quit();
+            EXPECT_EQ(base::File::FILE_OK, error);
+          },
+          &run_loop));
+  run_loop.Run();
+
+  // There should be dir/photo2.jpg which was renamed from dir/photo.jpg.
+  {
+    base::RunLoop run_loop;
+    root_->GetExtraFileMetadata(
+        base::FilePath(FILE_PATH_LITERAL("dir/photo2.jpg")),
+        base::BindOnce(
+            [](base::RunLoop* run_loop, base::File::Error error,
+               const ArcDocumentsProviderRoot::ExtraFileMetadata& metadata) {
+              run_loop->Quit();
+              EXPECT_EQ(base::File::FILE_OK, error);
+            },
+            &run_loop));
+    run_loop.Run();
+  }
+
+  // The source file should be gone by rename.
+  {
+    base::RunLoop run_loop;
+    root_->GetExtraFileMetadata(
+        base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg")),
+        base::BindOnce(
+            [](base::RunLoop* run_loop, base::File::Error error,
+               const ArcDocumentsProviderRoot::ExtraFileMetadata& metadata) {
+              run_loop->Quit();
+              EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, error);
+            },
+            &run_loop));
+    run_loop.Run();
+  }
+}
+
 TEST_F(ArcDocumentsProviderRootTest, RenameFileNotRenamable) {
   base::RunLoop run_loop;
   root_->MoveFileLocal(
@@ -1284,6 +1404,50 @@
                 .document_id);
 }
 
+TEST_F(ArcDocumentsProviderRootTest, MoveFileThenGetMetadataClearsCache) {
+  base::RunLoop run_loop;
+  root_->MoveFileLocal(
+      base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg")),
+      base::FilePath(FILE_PATH_LITERAL("photo.jpg")),
+      base::BindOnce(
+          [](base::RunLoop* run_loop, base::File::Error error) {
+            run_loop->Quit();
+            EXPECT_EQ(base::File::FILE_OK, error);
+          },
+          &run_loop));
+  run_loop.Run();
+
+  // There should be photo.jpg which was moved from dir/photo.jpg.
+  {
+    base::RunLoop run_loop;
+    root_->GetExtraFileMetadata(
+        base::FilePath(FILE_PATH_LITERAL("photo.jpg")),
+        base::BindOnce(
+            [](base::RunLoop* run_loop, base::File::Error error,
+               const ArcDocumentsProviderRoot::ExtraFileMetadata& metadata) {
+              run_loop->Quit();
+              EXPECT_EQ(base::File::FILE_OK, error);
+            },
+            &run_loop));
+    run_loop.Run();
+  }
+
+  // The source file should be gone by move.
+  {
+    base::RunLoop run_loop;
+    root_->GetExtraFileMetadata(
+        base::FilePath(FILE_PATH_LITERAL("dir/photo.jpg")),
+        base::BindOnce(
+            [](base::RunLoop* run_loop, base::File::Error error,
+               const ArcDocumentsProviderRoot::ExtraFileMetadata& metadata) {
+              run_loop->Quit();
+              EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, error);
+            },
+            &run_loop));
+    run_loop.Run();
+  }
+}
+
 TEST_F(ArcDocumentsProviderRootTest, MoveFileWithDifferentName) {
   base::RunLoop run_loop;
   root_->MoveFileLocal(
diff --git a/chrome/browser/ash/crosapi/browser_data_migrator.cc b/chrome/browser/ash/crosapi/browser_data_migrator.cc
index e42e8db..9e67d8a 100644
--- a/chrome/browser/ash/crosapi/browser_data_migrator.cc
+++ b/chrome/browser/ash/crosapi/browser_data_migrator.cc
@@ -233,9 +233,8 @@
   }
 
   // Check if profile migration is enabled. If not immediately return.
-  if (!crosapi::browser_util::
-          IsProfileMigrationEnabledWithUserAndPolicyInitState(
-              user, policy_init_state)) {
+  if (!crosapi::browser_util::IsProfileMigrationEnabled(user,
+                                                        policy_init_state)) {
     if (crosapi::browser_util::IsLacrosEnabledForMigration(user,
                                                            policy_init_state) ||
         base::CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/chrome/browser/ash/crosapi/browser_util.cc b/chrome/browser/ash/crosapi/browser_util.cc
index 3bfe90f..a1f4262 100644
--- a/chrome/browser/ash/crosapi/browser_util.cc
+++ b/chrome/browser/ash/crosapi/browser_util.cc
@@ -165,7 +165,9 @@
 
   // If profile migration is enabled, the completion of it is necessary for
   // Lacros to be enabled.
-  if (check_migration_status && IsProfileMigrationEnabled()) {
+  if (check_migration_status &&
+      !base::FeatureList::IsEnabled(
+          ash::standalone_browser::features::kLacrosProfileMigrationForceOff)) {
     PrefService* local_state = g_browser_process->local_state();
     // Note that local_state can be nullptr in tests.
     if (local_state && !ash::standalone_browser::migrator_util::
@@ -307,29 +309,24 @@
                                  /*check_migration_status=*/false);
 }
 
-bool IsProfileMigrationEnabled() {
-  return IsProfileMigrationEnabledWithUserAndPolicyInitState(
-      GetPrimaryUser(), PolicyInitState::kAfterInit);
-}
-
-bool IsProfileMigrationEnabledWithUserAndPolicyInitState(
-    const user_manager::User* user,
-    PolicyInitState policy_init_state) {
+bool IsProfileMigrationEnabled(const user_manager::User* user,
+                               PolicyInitState policy_init_state) {
   return !base::FeatureList::IsEnabled(ash::standalone_browser::features::
                                            kLacrosProfileMigrationForceOff) &&
          !IsAshWebBrowserEnabledForMigration(user, policy_init_state);
 }
 
 bool IsProfileMigrationAvailable() {
-  if (!IsProfileMigrationEnabled()) {
+  auto* user_manager = UserManager::Get();
+  auto* primary_user = user_manager->GetPrimaryUser();
+  if (!IsProfileMigrationEnabled(primary_user, PolicyInitState::kAfterInit)) {
     return false;
   }
 
   // If migration is already completed, it is not necessary to run again.
   if (ash::standalone_browser::migrator_util::
-          IsProfileMigrationCompletedForUser(
-              UserManager::Get()->GetLocalState(),
-              UserManager::Get()->GetPrimaryUser()->username_hash())) {
+          IsProfileMigrationCompletedForUser(user_manager->GetLocalState(),
+                                             primary_user->username_hash())) {
     return false;
   }
 
diff --git a/chrome/browser/ash/crosapi/browser_util.h b/chrome/browser/ash/crosapi/browser_util.h
index 7bb9ddcd..947a89d9 100644
--- a/chrome/browser/ash/crosapi/browser_util.h
+++ b/chrome/browser/ash/crosapi/browser_util.h
@@ -330,11 +330,8 @@
 
 // Returns true if profile migraiton is enabled. If profile migration is
 // enabled, the completion of it is required to enable Lacros.
-bool IsProfileMigrationEnabled();
-
-bool IsProfileMigrationEnabledWithUserAndPolicyInitState(
-    const user_manager::User* user,
-    PolicyInitState policy_init_state);
+bool IsProfileMigrationEnabled(const user_manager::User* user,
+                               PolicyInitState policy_init_state);
 
 // Returns true if the profile migration is enabled, but not yet completed.
 bool IsProfileMigrationAvailable();
diff --git a/chrome/browser/ash/crosapi/crosapi_ash.cc b/chrome/browser/ash/crosapi/crosapi_ash.cc
index 7e6ffd3..c2d71c6 100644
--- a/chrome/browser/ash/crosapi/crosapi_ash.cc
+++ b/chrome/browser/ash/crosapi/crosapi_ash.cc
@@ -646,7 +646,7 @@
 }
 
 void CrosapiAsh::BindInSessionAuth(
-    mojo::PendingReceiver<mojom::InSessionAuth> receiver) {
+    mojo::PendingReceiver<chromeos::auth::mojom::InSessionAuth> receiver) {
   in_session_auth_ash_->BindReceiver(std::move(receiver));
 }
 
diff --git a/chrome/browser/ash/crosapi/crosapi_ash.h b/chrome/browser/ash/crosapi/crosapi_ash.h
index 4a0c7aa..4d9d9c7 100644
--- a/chrome/browser/ash/crosapi/crosapi_ash.h
+++ b/chrome/browser/ash/crosapi/crosapi_ash.h
@@ -261,7 +261,8 @@
   void BindImageWriter(
       mojo::PendingReceiver<mojom::ImageWriter> receiver) override;
   void BindInSessionAuth(
-      mojo::PendingReceiver<mojom::InSessionAuth> receiver) override;
+      mojo::PendingReceiver<chromeos::auth::mojom::InSessionAuth> receiver)
+      override;
   void BindKerberosInBrowser(
       mojo::PendingReceiver<mojom::KerberosInBrowser> receiver) override;
   void BindKeystoreService(
diff --git a/chrome/browser/ash/crosapi/crosapi_util.cc b/chrome/browser/ash/crosapi/crosapi_util.cc
index ab701ac..c68a6a0 100644
--- a/chrome/browser/ash/crosapi/crosapi_util.cc
+++ b/chrome/browser/ash/crosapi/crosapi_util.cc
@@ -42,6 +42,7 @@
 #include "chromeos/ash/components/settings/cros_settings_provider.h"
 #include "chromeos/ash/components/system/statistics_provider.h"
 #include "chromeos/components/cdm_factory_daemon/mojom/browser_cdm_factory.mojom.h"
+#include "chromeos/components/in_session_auth/mojom/in_session_auth.mojom.h"
 #include "chromeos/components/payments/mojom/payment_app.mojom.h"
 #include "chromeos/components/remote_apps/mojom/remote_apps.mojom.h"
 #include "chromeos/components/sensors/mojom/cros_sensor_service.mojom.h"
@@ -95,7 +96,6 @@
 #include "chromeos/crosapi/mojom/holding_space_service.mojom.h"
 #include "chromeos/crosapi/mojom/identity_manager.mojom.h"
 #include "chromeos/crosapi/mojom/image_writer.mojom.h"
-#include "chromeos/crosapi/mojom/in_session_auth.mojom.h"
 #include "chromeos/crosapi/mojom/kerberos_in_browser.mojom.h"
 #include "chromeos/crosapi/mojom/keystore_service.mojom.h"
 #include "chromeos/crosapi/mojom/kiosk_session_service.mojom.h"
@@ -362,7 +362,7 @@
     MakeInterfaceVersionEntry<crosapi::mojom::IdleService>(),
     MakeInterfaceVersionEntry<crosapi::mojom::ImageWriter>(),
     MakeInterfaceVersionEntry<crosapi::mojom::InputMethodTestInterface>(),
-    MakeInterfaceVersionEntry<crosapi::mojom::InSessionAuth>(),
+    MakeInterfaceVersionEntry<chromeos::auth::mojom::InSessionAuth>(),
     MakeInterfaceVersionEntry<crosapi::mojom::KerberosInBrowser>(),
     MakeInterfaceVersionEntry<crosapi::mojom::KeystoreService>(),
     MakeInterfaceVersionEntry<crosapi::mojom::KioskSessionService>(),
diff --git a/chrome/browser/ash/crosapi/in_session_auth_ash.cc b/chrome/browser/ash/crosapi/in_session_auth_ash.cc
index d3e7f248..ed98f9d 100644
--- a/chrome/browser/ash/crosapi/in_session_auth_ash.cc
+++ b/chrome/browser/ash/crosapi/in_session_auth_ash.cc
@@ -16,17 +16,18 @@
 #include "chrome/browser/ash/login/quick_unlock/quick_unlock_factory.h"
 #include "chrome/browser/ash/login/quick_unlock/quick_unlock_storage.h"
 #include "chromeos/ash/components/osauth/public/auth_session_storage.h"
-#include "chromeos/crosapi/mojom/in_session_auth.mojom.h"
+#include "chromeos/components/in_session_auth/mojom/in_session_auth.mojom.h"
 
 namespace crosapi {
 
-ash::InSessionAuthDialogController::Reason ToAshReason(mojom::Reason reason) {
+ash::InSessionAuthDialogController::Reason ToAshReason(
+    chromeos::auth::mojom::Reason reason) {
   switch (reason) {
-    case mojom::Reason::kAccessPasswordManager:
+    case chromeos::auth::mojom::Reason::kAccessPasswordManager:
       return ash::InSessionAuthDialogController::kAccessPasswordManager;
-    case mojom::Reason::kModifyAuthFactors:
+    case chromeos::auth::mojom::Reason::kModifyAuthFactors:
       return ash::InSessionAuthDialogController::kModifyAuthFactors;
-    case mojom::Reason::kModifyAuthFactorsMultidevice:
+    case chromeos::auth::mojom::Reason::kModifyAuthFactorsMultidevice:
       return ash::InSessionAuthDialogController::kModifyAuthFactorsMultidevice;
   }
 }
@@ -39,7 +40,7 @@
   receivers_.Add(this, std::move(receiver));
 }
 
-void InSessionAuthAsh::RequestToken(mojom::Reason reason,
+void InSessionAuthAsh::RequestToken(chromeos::auth::mojom::Reason reason,
                                     const absl::optional<std::string>& prompt,
                                     RequestTokenCallback callback) {
   ash::Shell::Get()->in_session_auth_dialog_controller()->ShowAuthDialog(
@@ -48,7 +49,7 @@
                      weak_factory_.GetWeakPtr(), std::move(callback)));
 }
 
-void InSessionAuthAsh::CheckToken(mojom::Reason reason,
+void InSessionAuthAsh::CheckToken(chromeos::auth::mojom::Reason reason,
                                   const std::string& token,
                                   CheckTokenCallback callback) {
   bool token_valid;
@@ -84,7 +85,8 @@
                                       const ash::AuthProofToken& token,
                                       base::TimeDelta timeout) {
   std::move(callback).Run(
-      success ? mojom::RequestTokenReply::New(token, timeout) : nullptr);
+      success ? chromeos::auth::mojom::RequestTokenReply::New(token, timeout)
+              : nullptr);
 }
 
 }  // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/in_session_auth_ash.h b/chrome/browser/ash/crosapi/in_session_auth_ash.h
index 658e4c0..4e75bff 100644
--- a/chrome/browser/ash/crosapi/in_session_auth_ash.h
+++ b/chrome/browser/ash/crosapi/in_session_auth_ash.h
@@ -7,8 +7,8 @@
 
 #include "base/memory/weak_ptr.h"
 #include "chromeos/ash/components/osauth/public/common_types.h"
-#include "chromeos/crosapi/mojom/in_session_auth.mojom-shared.h"
-#include "chromeos/crosapi/mojom/in_session_auth.mojom.h"
+#include "chromeos/components/in_session_auth/mojom/in_session_auth.mojom-shared.h"
+#include "chromeos/components/in_session_auth/mojom/in_session_auth.mojom.h"
 #include "mojo/public/cpp/bindings/receiver_set.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -17,7 +17,7 @@
 // This is the ash-chrome implementation of the InSessionAuth mojo interface.
 // Used by lacros-chrome to call into ash authentication backends to
 // authenticate users in session.
-class InSessionAuthAsh : public mojom::InSessionAuth {
+class InSessionAuthAsh : public chromeos::auth::mojom::InSessionAuth {
  public:
   InSessionAuthAsh();
   InSessionAuthAsh(const InSessionAuthAsh&) = delete;
@@ -27,10 +27,10 @@
   void BindReceiver(mojo::PendingReceiver<InSessionAuth> receiver);
 
   // crosapi::mojom::InSessionAuth
-  void RequestToken(mojom::Reason reason,
+  void RequestToken(chromeos::auth::mojom::Reason reason,
                     const absl::optional<std::string>& prompt,
                     RequestTokenCallback callback) override;
-  void CheckToken(mojom::Reason reason,
+  void CheckToken(chromeos::auth::mojom::Reason reason,
                   const std::string& token,
                   CheckTokenCallback callback) override;
   void InvalidateToken(const std::string& token) override;
@@ -43,7 +43,7 @@
                       const ash::AuthProofToken& token,
                       base::TimeDelta timeout);
 
-  mojo::ReceiverSet<mojom::InSessionAuth> receivers_;
+  mojo::ReceiverSet<chromeos::auth::mojom::InSessionAuth> receivers_;
 
   base::WeakPtrFactory<InSessionAuthAsh> weak_factory_{this};
 };
diff --git a/chrome/browser/ash/drive/drive_integration_service.cc b/chrome/browser/ash/drive/drive_integration_service.cc
index d9f7f1a..694b978 100644
--- a/chrome/browser/ash/drive/drive_integration_service.cc
+++ b/chrome/browser/ash/drive/drive_integration_service.cc
@@ -950,12 +950,9 @@
       logger_.Log(logging::LOGGING_INFO, "Drive mount point is removed");
     }
   }
-  GetDriveFsHost()->Unmount();
 
-  if (pinning_manager_) {
-    pinning_manager_->Stop();
-    pinning_manager_.reset();
-  }
+  GetDriveFsHost()->Unmount();
+  pinning_manager_.reset();
 }
 
 void DriveIntegrationService::MaybeRemountFileSystem(
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest.cc b/chrome/browser/ash/file_manager/file_manager_browsertest.cc
index d55aa16..95cc6c11 100644
--- a/chrome/browser/ash/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/ash/file_manager/file_manager_browsertest.cc
@@ -338,22 +338,21 @@
         TestCase("fileDisplayUsb")
             .NewDirectoryTree()
             .FeatureIds({"screenplay-ade01078-3b79-41d2-953e-e22a544a28b3"}),
-        // TODO(b/301341566): enable the tests
         TestCase("fileDisplayUsbPartition").NewDirectoryTree(),
         TestCase("fileDisplayUsbPartition")
             .EnableSinglePartitionFormat()
             .NewDirectoryTree(),
         TestCase("fileDisplayUsbPartitionSort").NewDirectoryTree(),
         TestCase("fileDisplayPartitionFileTable").NewDirectoryTree(),
-        // TestCase("fileDisplayWithoutVolumesThenMountDownloads")
-        //     .DontMountVolumes()
-        //     .NewDirectoryTree(),
-        // TestCase("fileDisplayWithoutVolumesThenMountDrive")
-        //     .DontMountVolumes()
-        //     .NewDirectoryTree(),
-        // TestCase("fileDisplayWithoutDrive")
-        //     .DontMountVolumes()
-        //     .NewDirectoryTree(),
+        TestCase("fileDisplayWithoutVolumesThenMountDownloads")
+            .DontMountVolumes()
+            .NewDirectoryTree(),
+        TestCase("fileDisplayWithoutVolumesThenMountDrive")
+            .DontMountVolumes()
+            .NewDirectoryTree(),
+        TestCase("fileDisplayWithoutDrive")
+            .DontMountVolumes()
+            .NewDirectoryTree(),
         TestCase("fileDisplayWithHiddenVolume").NewDirectoryTree(),
         TestCase("fileDisplayMountWithFakeItemSelected").NewDirectoryTree(),
         TestCase("fileDisplayUnmountDriveWithSharedWithMeSelected")
@@ -607,11 +606,8 @@
             .NewDirectoryTree(),
         TestCase("checkDeleteEnabledInRecents").NewDirectoryTree(),
         TestCase("checkGoToFileLocationEnabledInRecents").NewDirectoryTree(),
-// TODO(https://crbug.com/1425820): Fix flakes and re-enable.
-#if !BUILDFLAG(IS_CHROMEOS)
         TestCase("checkGoToFileLocationDisabledInMultipleSelection")
             .NewDirectoryTree(),
-#endif
         TestCase("checkEncryptedCrossVolumeMoveDisabled").NewDirectoryTree(),
         TestCase("checkEncryptedMoveEnabled").NewDirectoryTree(),
         // Section end - browser tests for new directory tree
@@ -1511,22 +1507,15 @@
             .WithBrowser()
             .NewDirectoryTree(),
         TestCase("openFileDialogGuestOs").WithBrowser().NewDirectoryTree(),
-// TODO(crbug.com/1425820): Re-enable this test.
-#if !defined(LEAK_SANITIZER) || !BUILDFLAG(IS_CHROMEOS) || \
-    !defined(ADDRESS_SANITIZER)
         TestCase("openFileDialogGuestOs")
             .WithBrowser()
             .InIncognito()
             .NewDirectoryTree(),
-#endif
         TestCase("saveFileDialogGuestOs").WithBrowser().NewDirectoryTree(),
-// TODO(crbug.com/1425820): Re-enable this test.
-#if !BUILDFLAG(IS_CHROMEOS)
         TestCase("saveFileDialogGuestOs")
             .WithBrowser()
             .InIncognito()
             .NewDirectoryTree(),
-#endif
         TestCase("openFileDialogDownloads")
             .WithBrowser()
             .NewDirectoryTree()
diff --git a/chrome/browser/ash/file_system_provider/notification_manager.cc b/chrome/browser/ash/file_system_provider/notification_manager.cc
index 302f55e..60baacc 100644
--- a/chrome/browser/ash/file_system_provider/notification_manager.cc
+++ b/chrome/browser/ash/file_system_provider/notification_manager.cc
@@ -75,6 +75,7 @@
 void NotificationManager::OnAppImageUpdated(
     const std::string& id,
     const gfx::ImageSkia& image,
+    bool is_placeholder_icon,
     const absl::optional<gfx::ImageSkia>& badge_image) {
   extension_icon_ = ui::ImageModel::FromImageSkia(image);
   ShowNotification();
diff --git a/chrome/browser/ash/file_system_provider/notification_manager.h b/chrome/browser/ash/file_system_provider/notification_manager.h
index 87cf8c5..2e74613 100644
--- a/chrome/browser/ash/file_system_provider/notification_manager.h
+++ b/chrome/browser/ash/file_system_provider/notification_manager.h
@@ -52,6 +52,7 @@
   void OnAppImageUpdated(
       const std::string& id,
       const gfx::ImageSkia& image,
+      bool is_placeholder_icon,
       const absl::optional<gfx::ImageSkia>& badge_image) override;
 
   // message_center::NotificationObserver overrides:
diff --git a/chrome/browser/ash/fileapi/file_accumulator.cc b/chrome/browser/ash/fileapi/file_accumulator.cc
new file mode 100644
index 0000000..73f94b0e
--- /dev/null
+++ b/chrome/browser/ash/fileapi/file_accumulator.cc
@@ -0,0 +1,44 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/fileapi/file_accumulator.h"
+
+#include <algorithm>
+
+namespace ash {
+
+FileAccumulator::FileAccumulator(size_t max_capacity)
+    : max_capacity_(max_capacity), sealed_(false) {}
+
+FileAccumulator::~FileAccumulator() = default;
+
+bool FileAccumulator::Add(const RecentFile& file) {
+  if (sealed_) {
+    return false;
+  }
+
+  files_.emplace_back(file);
+  std::push_heap(files_.begin(), files_.end(), RecentFileComparator());
+  if (files_.size() > max_capacity_) {
+    std::pop_heap(files_.begin(), files_.end(), RecentFileComparator());
+    files_.pop_back();
+  }
+
+  return true;
+}
+
+const std::vector<RecentFile>& FileAccumulator::Get() {
+  if (!sealed_) {
+    sealed_ = true;
+    std::sort_heap(files_.begin(), files_.end(), RecentFileComparator());
+  }
+  return files_;
+}
+
+void FileAccumulator::Clear() {
+  files_.clear();
+  sealed_ = false;
+}
+
+}  // namespace ash
diff --git a/chrome/browser/ash/fileapi/file_accumulator.h b/chrome/browser/ash/fileapi/file_accumulator.h
new file mode 100644
index 0000000..7a8c3b6
--- /dev/null
+++ b/chrome/browser/ash/fileapi/file_accumulator.h
@@ -0,0 +1,65 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ASH_FILEAPI_FILE_ACCUMULATOR_H_
+#define CHROME_BROWSER_ASH_FILEAPI_FILE_ACCUMULATOR_H_
+
+#include <vector>
+
+#include "chrome/browser/ash/fileapi/recent_file.h"
+
+namespace ash {
+
+// Accumulator of files located via search operation. The accumulator has a
+// limited capacity. Files are sorted based on the RecentFileComparator class.
+// If one adds n > max_capacity files, (n - max_capacity) files are discarded
+// based on the order given by the comparator class.
+//
+// Typical use consists of adding a number of files, then Get'ing the content.
+// Once the content is Get'ed, the accumulator is sealed, meaning no new files
+// may be added to the accumulator. To unseal the accumulator, call the Clear
+// method on it, which also removes all stored files.
+//
+//   FilesAccumulator<RecentFilesComparator> acc(100);
+//   acc.Add(recent_file_1);
+//   ..
+//   acc.Add(recent_file_n);
+//   std::vector<RecentFile> content = acc.Get();
+class FileAccumulator {
+ public:
+  // Creates an accumulator with the given capacity. The capacity
+  // limits the maximum number of files that can be added via the Add method.
+  explicit FileAccumulator(size_t max_capacity);
+
+  ~FileAccumulator();
+
+  // Adds a single file to the accumulator. The return value indicates if the
+  // file has been added or not. A file may not be added if the accumulator is
+  // sealed.
+  bool Add(const RecentFile& file);
+
+  // Returns the content of this accumulator. The first time this method is
+  // called it "seals" this accumulator, re-orders the files from a heap to a
+  // simple vector. This method can be called multiple times.
+  const std::vector<RecentFile>& Get();
+
+  // Clears the accumulator and unseals it.
+  void Clear();
+
+  // Returns the maximum number of recent files that are can be stored in this
+  // cache.
+  size_t max_capacity() const { return max_capacity_; }
+
+ private:
+  // The maximum number of recent files kept in this cache.
+  const size_t max_capacity_;
+  // Whether or not the accumulator is in the sealed state.
+  bool sealed_;
+  // The content of the cache, kept sorted by the modified time.
+  std::vector<RecentFile> files_;
+};
+
+}  // namespace ash
+
+#endif  // CHROME_BROWSER_ASH_FILEAPI_FOUND_FILES_CACHE_H_
diff --git a/chrome/browser/ash/fileapi/file_accumulator_unittest.cc b/chrome/browser/ash/fileapi/file_accumulator_unittest.cc
new file mode 100644
index 0000000..feb3495
--- /dev/null
+++ b/chrome/browser/ash/fileapi/file_accumulator_unittest.cc
@@ -0,0 +1,72 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/fileapi/file_accumulator.h"
+
+#include "base/files/file_path.h"
+#include "base/run_loop.h"
+#include "base/test/task_environment.h"
+#include "base/time/time.h"
+#include "chrome/browser/ash/fileapi/recent_file.h"
+#include "storage/browser/file_system/file_system_url.h"
+#include "storage/common/file_system/file_system_types.h"
+#include "testing/gmock/include/gmock/gmock-matchers.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/storage_key/storage_key.h"
+
+namespace ash {
+namespace {
+
+MATCHER(RecentFilesEq, "") {
+  RecentFile a = std::get<0>(arg);
+  RecentFile b = std::get<1>(arg);
+  return a.url() == b.url() && a.last_modified() == b.last_modified();
+}
+
+RecentFile MakeRecentFile(const std::string& name,
+                          const base::Time& last_modified) {
+  storage::FileSystemURL url = storage::FileSystemURL::CreateForTest(
+      blink::StorageKey(), storage::kFileSystemTypeLocal, base::FilePath(name));
+  return RecentFile(url, last_modified);
+}
+
+class FileAccumulatorTest : public testing::Test {
+ protected:
+  base::test::SingleThreadTaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+};
+
+TEST_F(FileAccumulatorTest, AddGetClear) {
+  RecentFile a_file = MakeRecentFile("a.jpg", base::Time::Now());
+  RecentFile b_file = MakeRecentFile("b.jpg", base::Time::Now());
+
+  FileAccumulator acc(10);
+  EXPECT_TRUE(acc.Add(a_file));
+  EXPECT_THAT(acc.Get(), testing::Pointwise(RecentFilesEq(), {a_file}));
+  EXPECT_FALSE(acc.Add(b_file));
+  acc.Clear();
+  EXPECT_TRUE(acc.Add(b_file));
+  EXPECT_THAT(acc.Get(), testing::Pointwise(RecentFilesEq(), {b_file}));
+}
+
+TEST_F(FileAccumulatorTest, CapacityAndOrder) {
+  base::Time now = base::Time::Now();
+  FileAccumulator acc(2);
+  // File a.jpg is the most recently modified, then c.jpg, then b.jpg.
+  EXPECT_TRUE(acc.Add(MakeRecentFile("a.jpg", now - base::Minutes(1))));
+  EXPECT_TRUE(acc.Add(MakeRecentFile("b.jpg", now - base::Minutes(5))));
+  EXPECT_TRUE(acc.Add(MakeRecentFile("c.jpg", now - base::Minutes(2))));
+  std::vector<RecentFile> content_1 = acc.Get();
+  // Expect a.jpg followed by c.jpg, based on last modified time.
+  EXPECT_EQ(content_1.size(), 2u);
+  EXPECT_EQ(content_1[0].url().path().value(), "a.jpg");
+  EXPECT_EQ(content_1[1].url().path().value(), "c.jpg");
+
+  EXPECT_FALSE(acc.Add(MakeRecentFile("d.jpg", now - base::Minutes(3))));
+  std::vector<RecentFile> content_2 = acc.Get();
+  EXPECT_THAT(content_2, testing::Pointwise(RecentFilesEq(), content_1));
+}
+
+}  // namespace
+}  // namespace ash
diff --git a/chrome/browser/ash/fileapi/recent_disk_source.cc b/chrome/browser/ash/fileapi/recent_disk_source.cc
index 6bb011d..5f079c1 100644
--- a/chrome/browser/ash/fileapi/recent_disk_source.cc
+++ b/chrome/browser/ash/fileapi/recent_disk_source.cc
@@ -101,7 +101,6 @@
   DCHECK(build_start_time_.is_null());
   DCHECK_EQ(0, inflight_readdirs_);
   DCHECK_EQ(0, inflight_stats_);
-  DCHECK(recent_files_.empty());
 
   // Return immediately if mount point does not exist.
   storage::ExternalMountPoints* mount_points =
@@ -113,8 +112,8 @@
   }
 
   params_.emplace(std::move(params));
-
   DCHECK(params_.has_value());
+  accumulator_ = std::make_unique<FileAccumulator>(params_.value().max_files());
 
   build_start_time_ = base::TimeTicks::Now();
 
@@ -196,9 +195,7 @@
 
   if (result == base::File::FILE_OK &&
       info.last_modified >= params_.value().cutoff_time()) {
-    recent_files_.emplace(RecentFile(url, info.last_modified));
-    while (recent_files_.size() > params_.value().max_files())
-      recent_files_.pop();
+    accumulator_->Add(RecentFile(url, info.last_modified));
   }
 
   --inflight_stats_;
@@ -212,11 +209,8 @@
     return;
 
   // All reads/scans completed.
-  std::vector<RecentFile> files;
-  while (!recent_files_.empty()) {
-    files.emplace_back(recent_files_.top());
-    recent_files_.pop();
-  }
+  std::vector<RecentFile> files = accumulator_->Get();
+  accumulator_.reset();
 
   DCHECK(!build_start_time_.is_null());
   UmaHistogramTimes(uma_histogram_name_,
@@ -230,7 +224,6 @@
   DCHECK(build_start_time_.is_null());
   DCHECK_EQ(0, inflight_readdirs_);
   DCHECK_EQ(0, inflight_stats_);
-  DCHECK(recent_files_.empty());
 
   std::move(params.callback()).Run(std::move(files));
 }
diff --git a/chrome/browser/ash/fileapi/recent_disk_source.h b/chrome/browser/ash/fileapi/recent_disk_source.h
index ce3ee1f..375d1ca 100644
--- a/chrome/browser/ash/fileapi/recent_disk_source.h
+++ b/chrome/browser/ash/fileapi/recent_disk_source.h
@@ -6,7 +6,6 @@
 #define CHROME_BROWSER_ASH_FILEAPI_RECENT_DISK_SOURCE_H_
 
 #include <memory>
-#include <queue>
 #include <string>
 #include <vector>
 
@@ -15,6 +14,7 @@
 #include "base/gtest_prod_util.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
+#include "chrome/browser/ash/fileapi/file_accumulator.h"
 #include "chrome/browser/ash/fileapi/recent_file.h"
 #include "chrome/browser/ash/fileapi/recent_model.h"
 #include "chrome/browser/ash/fileapi/recent_source.h"
@@ -84,8 +84,7 @@
   // Number of GetMetadata() calls in flight.
   int inflight_stats_ = 0;
   // Most recently modified files.
-  std::priority_queue<RecentFile, std::vector<RecentFile>, RecentFileComparator>
-      recent_files_;
+  std::unique_ptr<FileAccumulator> accumulator_;
 
   base::WeakPtrFactory<RecentDiskSource> weak_ptr_factory_{this};
 };
diff --git a/chrome/browser/ash/fileapi/recent_model.cc b/chrome/browser/ash/fileapi/recent_model.cc
index 78c324d..1e0db7a4 100644
--- a/chrome/browser/ash/fileapi/recent_model.cc
+++ b/chrome/browser/ash/fileapi/recent_model.cc
@@ -37,6 +37,9 @@
 // not strictly honored.
 constexpr base::TimeDelta kCacheExpiration = base::Seconds(10);
 
+// The default number of files collected from each recent source.
+constexpr size_t kMaxFiles = 1000u;
+
 std::vector<std::unique_ptr<RecentSource>> CreateDefaultSources(
     Profile* profile) {
   std::vector<std::unique_ptr<RecentSource>> sources;
@@ -89,15 +92,19 @@
 
 // static
 std::unique_ptr<RecentModel> RecentModel::CreateForTest(
-    std::vector<std::unique_ptr<RecentSource>> sources) {
-  return base::WrapUnique(new RecentModel(std::move(sources)));
+    std::vector<std::unique_ptr<RecentSource>> sources,
+    size_t max_files) {
+  return base::WrapUnique(new RecentModel(std::move(sources), max_files));
 }
 
 RecentModel::RecentModel(Profile* profile)
-    : RecentModel(CreateDefaultSources(profile)) {}
+    : RecentModel(CreateDefaultSources(profile), kMaxFiles) {}
 
-RecentModel::RecentModel(std::vector<std::unique_ptr<RecentSource>> sources)
-    : sources_(std::move(sources)), current_sequence_id_(0) {
+RecentModel::RecentModel(std::vector<std::unique_ptr<RecentSource>> sources,
+                         size_t max_files)
+    : sources_(std::move(sources)),
+      accumulator_(max_files),
+      current_sequence_id_(0) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 }
 
@@ -146,7 +153,6 @@
 
   // Start building a recent file list.
   DCHECK_EQ(0, num_inflight_sources_);
-  DCHECK(intermediate_files_.empty());
   DCHECK(build_start_time_.is_null());
 
   build_start_time_ = base::TimeTicks::Now();
@@ -160,6 +166,7 @@
   // cutoff_time is the oldest modified time for a file to be considered recent.
   base::Time cutoff_time = base::Time::Now() - now_delta;
 
+  accumulator_.Clear();
   uint32_t run_on_sequence_id = current_sequence_id_;
   // If there is no scan timeout we set the end_time, i.e., the time by which
   // the scan is supposed to be done, to maximum possible time. In the current
@@ -170,11 +177,11 @@
 
   for (const auto& source : sources_) {
     source->GetRecentFiles(RecentSource::Params(
-        file_system_context, origin, max_files_, query, cutoff_time, end_time,
-        file_type,
+        file_system_context, origin, accumulator_.max_capacity(), query,
+        cutoff_time, end_time, file_type,
         base::BindOnce(&RecentModel::OnGetRecentFiles,
                        weak_ptr_factory_.GetWeakPtr(), run_on_sequence_id,
-                       max_files_, cutoff_time, search_criteria)));
+                       cutoff_time, search_criteria)));
   }
   if (scan_timeout_duration_) {
     deadline_timer_.Start(
@@ -208,7 +215,6 @@
 }
 
 void RecentModel::OnGetRecentFiles(uint32_t run_on_sequence_id,
-                                   size_t max_files,
                                    const base::Time& cutoff_time,
                                    const SearchCriteria& search_criteria,
                                    std::vector<RecentFile> files) {
@@ -223,14 +229,10 @@
 
   for (const auto& file : files) {
     if (file.last_modified() >= cutoff_time) {
-      intermediate_files_.emplace(file);
+      accumulator_.Add(file);
     }
   }
 
-  while (intermediate_files_.size() > max_files) {
-    intermediate_files_.pop();
-  }
-
   --num_inflight_sources_;
   if (num_inflight_sources_ == 0) {
     OnGetRecentFilesCompleted(search_criteria);
@@ -248,17 +250,10 @@
   ++current_sequence_id_;
   deadline_timer_.Stop();
 
-  std::vector<RecentFile> files;
-  while (!intermediate_files_.empty()) {
-    files.emplace_back(intermediate_files_.top());
-    intermediate_files_.pop();
-  }
-  std::reverse(files.begin(), files.end());
-  cached_files_ = std::move(files);
+  cached_files_ = accumulator_.Get();
   cached_search_criteria_ = search_criteria;
 
   DCHECK(cached_files_.has_value());
-  DCHECK(intermediate_files_.empty());
 
   UMA_HISTOGRAM_TIMES(kLoadHistogramName,
                       base::TimeTicks::Now() - build_start_time_);
@@ -275,8 +270,9 @@
   DCHECK(pending_callbacks_.empty());
   DCHECK(!callbacks_to_call.empty());
   for (auto& callback : callbacks_to_call) {
-    std::move(callback).Run(cached_files_.value());
+    std::move(callback).Run(accumulator_.Get());
   }
+  accumulator_.Clear();
 }
 
 void RecentModel::ClearCache() {
@@ -285,10 +281,4 @@
   cached_files_.reset();
 }
 
-void RecentModel::SetMaxFilesForTest(size_t max_files) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
-  max_files_ = max_files;
-}
-
 }  // namespace ash
diff --git a/chrome/browser/ash/fileapi/recent_model.h b/chrome/browser/ash/fileapi/recent_model.h
index b8baec81..1f17ebc 100644
--- a/chrome/browser/ash/fileapi/recent_model.h
+++ b/chrome/browser/ash/fileapi/recent_model.h
@@ -6,15 +6,15 @@
 #define CHROME_BROWSER_ASH_FILEAPI_RECENT_MODEL_H_
 
 #include <memory>
-#include <queue>
+#include <string>
 #include <vector>
 
 #include "base/functional/callback_forward.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/weak_ptr.h"
-#include "base/synchronization/lock.h"
 #include "base/time/time.h"
 #include "base/timer/timer.h"
+#include "chrome/browser/ash/fileapi/file_accumulator.h"
 #include "chrome/browser/ash/fileapi/recent_file.h"
 #include "chrome/browser/ash/fileapi/recent_source.h"
 #include "components/keyed_service/core/keyed_service.h"
@@ -70,7 +70,8 @@
 
   // Creates an instance with given sources. Only for testing.
   static std::unique_ptr<RecentModel> CreateForTest(
-      std::vector<std::unique_ptr<RecentSource>> sources);
+      std::vector<std::unique_ptr<RecentSource>> sources,
+      size_t max_files);
 
   // Returns a list of recent files by querying sources.
   // Files are sorted by descending order of last modified time.
@@ -104,14 +105,14 @@
   static const char kLoadHistogramName[];
 
   explicit RecentModel(Profile* profile);
-  explicit RecentModel(std::vector<std::unique_ptr<RecentSource>> sources);
+  explicit RecentModel(std::vector<std::unique_ptr<RecentSource>> sources,
+                       size_t max_files);
 
   // The method called by each of the recent source workers, once they complete
   // their task. This method monitors the number of calls and once it is equal
   // to the number of started recent source workers, it calls
   // OnGetRecentFilesCompleted method.
   void OnGetRecentFiles(uint32_t run_on_sequence_id,
-                        size_t max_files,
                         const base::Time& cutoff_time,
                         const SearchCriteria& search_criteria,
                         std::vector<RecentFile> files);
@@ -125,13 +126,10 @@
   // The callback invoked by the deadline timer.
   void OnScanTimeout(const SearchCriteria& search_criteria);
 
-  void SetMaxFilesForTest(size_t max_files);
-
   std::vector<std::unique_ptr<RecentSource>> sources_;
 
-  // The maximum number of files in Recent. This value won't be changed from
-  // default except for unit tests.
-  size_t max_files_ = 1000;
+  // The accumulator of files found by various recent sources.
+  FileAccumulator accumulator_;
 
   // Cached GetRecentFiles() response.
   absl::optional<std::vector<RecentFile>> cached_files_ = absl::nullopt;
@@ -153,10 +151,6 @@
   // Number of in-flight sources building recent file lists.
   int num_inflight_sources_ = 0;
 
-  // Intermediate container of recent files while building a list.
-  std::priority_queue<RecentFile, std::vector<RecentFile>, RecentFileComparator>
-      intermediate_files_;
-
   // The deadline timer started when recent files are requested, if
   // scan_timeout_duration_ is set. This timer enforces the maximum time limit
   // the fetching of recent files can take. Once the timer goes off no more
diff --git a/chrome/browser/ash/fileapi/recent_model_unittest.cc b/chrome/browser/ash/fileapi/recent_model_unittest.cc
index 5184067..c0d3dcd5 100644
--- a/chrome/browser/ash/fileapi/recent_model_unittest.cc
+++ b/chrome/browser/ash/fileapi/recent_model_unittest.cc
@@ -105,13 +105,13 @@
             &profile_,
             base::BindRepeating(
                 [](const RecentSourceListFactory& source_list_factory,
-                   content::BrowserContext* context)
+                   size_t max_files, content::BrowserContext* context)
                     -> std::unique_ptr<KeyedService> {
-                  return RecentModel::CreateForTest(source_list_factory.Run());
+                  return RecentModel::CreateForTest(source_list_factory.Run(),
+                                                    max_files);
                 },
-                std::move(source_list_factory))));
+                std::move(source_list_factory), max_files)));
 
-    model->SetMaxFilesForTest(max_files);
     model->SetScanTimeout(base::Milliseconds(500));
 
     return GetRecentFiles(model, cutoff_delta, file_type, invalidate_cache);
@@ -249,7 +249,7 @@
 TEST(RecentModelCacheTest, GetRecentFiles_InvalidateCache) {
   content::BrowserTaskEnvironment task_environment;
   std::unique_ptr<RecentModel> model =
-      RecentModel::CreateForTest(BuildDefaultSources());
+      RecentModel::CreateForTest(BuildDefaultSources(), 10);
 
   std::vector<RecentFile> files1 = GetRecentFiles(
       model.get(), base::TimeDelta::Max(), RecentModel::FileType::kAll, false);
diff --git a/chrome/browser/ash/login/screens/osauth/base_osauth_setup_screen.h b/chrome/browser/ash/login/screens/osauth/base_osauth_setup_screen.h
index c59e6420..39b7872 100644
--- a/chrome/browser/ash/login/screens/osauth/base_osauth_setup_screen.h
+++ b/chrome/browser/ash/login/screens/osauth/base_osauth_setup_screen.h
@@ -22,8 +22,8 @@
 // See protected methods.
 
 class BaseOSAuthSetupScreen : public BaseScreen {
+ public:
   using InspectContextCallback = base::OnceCallback<void(UserContext*)>;
-
   BaseOSAuthSetupScreen(OobeScreenId screen_id,
                         OobeScreenPriority screen_priority);
 
diff --git a/chrome/browser/ash/login/screens/local_password_setup_screen.cc b/chrome/browser/ash/login/screens/osauth/local_password_setup_screen.cc
similarity index 67%
rename from chrome/browser/ash/login/screens/local_password_setup_screen.cc
rename to chrome/browser/ash/login/screens/osauth/local_password_setup_screen.cc
index 0f6c267..33221e5 100644
--- a/chrome/browser/ash/login/screens/local_password_setup_screen.cc
+++ b/chrome/browser/ash/login/screens/osauth/local_password_setup_screen.cc
@@ -2,19 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ash/login/screens/local_password_setup_screen.h"
+#include "chrome/browser/ash/login/screens/osauth/local_password_setup_screen.h"
 
 #include "ash/constants/ash_features.h"
 #include "base/check_op.h"
 #include "base/values.h"
 #include "chrome/browser/ash/login/quick_unlock/quick_unlock_factory.h"
-#include "chrome/browser/ash/login/quick_unlock/quick_unlock_storage.h"
 #include "chrome/browser/ash/login/screens/base_screen.h"
+#include "chrome/browser/ash/login/screens/osauth/base_osauth_setup_screen.h"
 #include "chrome/browser/ash/login/wizard_context.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/webui/ash/login/local_password_setup_handler.h"
-#include "chromeos/ash/components/login/auth/public/cryptohome_key_constants.h"
 #include "chromeos/ash/services/auth_factor_config/auth_factor_config.h"
 #include "chromeos/ash/services/auth_factor_config/in_process_instances.h"
 #include "chromeos/ash/services/auth_factor_config/public/mojom/auth_factor_config.mojom-forward.h"
@@ -45,8 +43,8 @@
 LocalPasswordSetupScreen::LocalPasswordSetupScreen(
     base::WeakPtr<LocalPasswordSetupView> view,
     const ScreenExitCallback& exit_callback)
-    : BaseScreen(LocalPasswordSetupView::kScreenId,
-                 OobeScreenPriority::DEFAULT),
+    : BaseOSAuthSetupScreen(LocalPasswordSetupView::kScreenId,
+                            OobeScreenPriority::DEFAULT),
       view_(std::move(view)),
       exit_callback_(exit_callback) {}
 
@@ -58,12 +56,17 @@
   if (!view_) {
     return;
   }
-  bool can_go_back = !context()->knowledge_factor_setup.local_password_forced;
-  view_->Show(can_go_back, context()->knowledge_factor_setup.auth_setup_flow ==
-                               WizardContext::AuthChangeFlow::kRecovery);
+  EstablishKnowledgeFactorGuard(base::BindOnce(
+      &LocalPasswordSetupScreen::DoShow, weak_factory_.GetWeakPtr()));
 }
 
-void LocalPasswordSetupScreen::HideImpl() {}
+void LocalPasswordSetupScreen::DoShow() {
+  bool can_go_back = !context()->knowledge_factor_setup.local_password_forced;
+  bool is_recovery_flow = context()->knowledge_factor_setup.auth_setup_flow ==
+                          WizardContext::AuthChangeFlow::kRecovery;
+  view_->Show(/*can_go_back=*/can_go_back,
+              /*is_recovery_flow=*/is_recovery_flow);
+}
 
 void LocalPasswordSetupScreen::OnUserAction(const base::Value::List& args) {
   const std::string& action_id = args[0].GetString();
@@ -74,21 +77,20 @@
         auth::GetPasswordFactorEditor(
             quick_unlock::QuickUnlockFactory::GetDelegate(),
             g_browser_process->local_state());
-
-    if (context()->knowledge_factor_setup.auth_setup_flow ==
-        WizardContext::AuthChangeFlow::kRecovery) {
-      password_factor_editor.UpdateLocalPassword(
-          GetToken(), password,
-          base::BindOnce(&LocalPasswordSetupScreen::OnSetLocalPassword,
-                         weak_factory_.GetWeakPtr()));
-      return;
+    switch (context()->knowledge_factor_setup.auth_setup_flow) {
+      case WizardContext::AuthChangeFlow::kInitialSetup:
+        password_factor_editor.SetLocalPassword(
+            GetToken(), password,
+            base::BindOnce(&LocalPasswordSetupScreen::OnSetLocalPassword,
+                           weak_factory_.GetWeakPtr()));
+        break;
+      case WizardContext::AuthChangeFlow::kRecovery:
+        password_factor_editor.UpdateLocalPassword(
+            GetToken(), password,
+            base::BindOnce(&LocalPasswordSetupScreen::OnSetLocalPassword,
+                           weak_factory_.GetWeakPtr()));
+        break;
     }
-
-    password_factor_editor.SetLocalPassword(
-        GetToken(), password,
-        base::BindOnce(&LocalPasswordSetupScreen::OnSetLocalPassword,
-                       weak_factory_.GetWeakPtr()));
-
     return;
   } else if (action_id == kUserActionBack) {
     exit_callback_.Run(Result::kBack);
@@ -97,7 +99,7 @@
     exit_callback_.Run(Result::kDone);
     return;
   }
-  BaseScreen::OnUserAction(args);
+  BaseOSAuthSetupScreen::OnUserAction(args);
 }
 
 void LocalPasswordSetupScreen::OnUpdateLocalPassword(
@@ -126,20 +128,4 @@
   view_->ShowLocalPasswordSetupSuccess();
 }
 
-std::string LocalPasswordSetupScreen::GetToken() const {
-  if (ash::features::ShouldUseAuthSessionStorage()) {
-    CHECK(context()->extra_factors_token.has_value());
-    return context()->extra_factors_token.value();
-  } else {
-    CHECK(context()->extra_factors_auth_session);
-
-    quick_unlock::QuickUnlockStorage* quick_unlock_storage =
-        quick_unlock::QuickUnlockFactory::GetForProfile(
-            ProfileManager::GetActiveUserProfile());
-    CHECK(quick_unlock_storage);
-    return quick_unlock_storage->CreateAuthToken(
-        *context()->extra_factors_auth_session);
-  }
-}
-
 }  // namespace ash
diff --git a/chrome/browser/ash/login/screens/local_password_setup_screen.h b/chrome/browser/ash/login/screens/osauth/local_password_setup_screen.h
similarity index 78%
rename from chrome/browser/ash/login/screens/local_password_setup_screen.h
rename to chrome/browser/ash/login/screens/osauth/local_password_setup_screen.h
index 391a130..a33cc52f 100644
--- a/chrome/browser/ash/login/screens/local_password_setup_screen.h
+++ b/chrome/browser/ash/login/screens/osauth/local_password_setup_screen.h
@@ -2,22 +2,22 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_ASH_LOGIN_SCREENS_LOCAL_PASSWORD_SETUP_SCREEN_H_
-#define CHROME_BROWSER_ASH_LOGIN_SCREENS_LOCAL_PASSWORD_SETUP_SCREEN_H_
+#ifndef CHROME_BROWSER_ASH_LOGIN_SCREENS_OSAUTH_LOCAL_PASSWORD_SETUP_SCREEN_H_
+#define CHROME_BROWSER_ASH_LOGIN_SCREENS_OSAUTH_LOCAL_PASSWORD_SETUP_SCREEN_H_
 
 #include <string>
 
 #include "base/functional/callback.h"
 #include "base/memory/weak_ptr.h"
 #include "base/values.h"
-#include "chrome/browser/ash/login/screens/base_screen.h"
+#include "chrome/browser/ash/login/screens/osauth/base_osauth_setup_screen.h"
 #include "chromeos/ash/services/auth_factor_config/public/mojom/auth_factor_config.mojom-shared.h"
 
 namespace ash {
 
 class LocalPasswordSetupView;
 
-class LocalPasswordSetupScreen : public BaseScreen {
+class LocalPasswordSetupScreen : public BaseOSAuthSetupScreen {
  public:
   using TView = LocalPasswordSetupView;
 
@@ -42,12 +42,11 @@
  private:
   // BaseScreen:
   void ShowImpl() override;
-  void HideImpl() override;
+  void DoShow();
   void OnUserAction(const base::Value::List& args) override;
 
   void OnUpdateLocalPassword(auth::mojom::ConfigureResult result);
   void OnSetLocalPassword(auth::mojom::ConfigureResult result);
-  std::string GetToken() const;
 
   base::WeakPtr<LocalPasswordSetupView> view_;
 
@@ -58,4 +57,4 @@
 
 }  // namespace ash
 
-#endif  // CHROME_BROWSER_ASH_LOGIN_SCREENS_LOCAL_PASSWORD_SETUP_SCREEN_H_
+#endif  // CHROME_BROWSER_ASH_LOGIN_SCREENS_OSAUTH_LOCAL_PASSWORD_SETUP_SCREEN_H_
diff --git a/chrome/browser/ash/login/screens/quick_start_screen.cc b/chrome/browser/ash/login/screens/quick_start_screen.cc
index 2e90df7b..b7b7c5c 100644
--- a/chrome/browser/ash/login/screens/quick_start_screen.cc
+++ b/chrome/browser/ash/login/screens/quick_start_screen.cc
@@ -39,8 +39,6 @@
       return "CancelAndReturnToSignin";
     case Result::WIFI_CREDENTIALS_RECEIVED:
       return "WifiCredentialsReceived";
-    case Result::WIFI_CONNECTED:
-      return "WifiConnected";
   }
 }
 
diff --git a/chrome/browser/ash/login/screens/quick_start_screen.h b/chrome/browser/ash/login/screens/quick_start_screen.h
index 359a3004..bf32f0f8 100644
--- a/chrome/browser/ash/login/screens/quick_start_screen.h
+++ b/chrome/browser/ash/login/screens/quick_start_screen.h
@@ -26,7 +26,6 @@
     CANCEL_AND_RETURN_TO_NETWORK,
     CANCEL_AND_RETURN_TO_SIGNIN,
     WIFI_CREDENTIALS_RECEIVED,
-    WIFI_CONNECTED
   };
 
   using ScreenExitCallback = base::RepeatingCallback<void(Result result)>;
diff --git a/chrome/browser/ash/login/wizard_controller.cc b/chrome/browser/ash/login/wizard_controller.cc
index c723a7c..ba9570e9 100644
--- a/chrome/browser/ash/login/wizard_controller.cc
+++ b/chrome/browser/ash/login/wizard_controller.cc
@@ -86,7 +86,6 @@
 #include "chrome/browser/ash/login/screens/kiosk_enable_screen.h"
 #include "chrome/browser/ash/login/screens/lacros_data_backward_migration_screen.h"
 #include "chrome/browser/ash/login/screens/lacros_data_migration_screen.h"
-#include "chrome/browser/ash/login/screens/local_password_setup_screen.h"
 #include "chrome/browser/ash/login/screens/local_state_error_screen.h"
 #include "chrome/browser/ash/login/screens/locale_switch_screen.h"
 #include "chrome/browser/ash/login/screens/management_transition_screen.h"
@@ -96,6 +95,7 @@
 #include "chrome/browser/ash/login/screens/network_screen.h"
 #include "chrome/browser/ash/login/screens/offline_login_screen.h"
 #include "chrome/browser/ash/login/screens/online_authentication_screen.h"
+#include "chrome/browser/ash/login/screens/osauth/local_password_setup_screen.h"
 #include "chrome/browser/ash/login/screens/packaged_license_screen.h"
 #include "chrome/browser/ash/login/screens/password_selection_screen.h"
 #include "chrome/browser/ash/login/screens/pin_setup_screen.h"
@@ -1846,7 +1846,6 @@
     case QuickStartScreen::Result::CANCEL_AND_RETURN_TO_WELCOME:
       ShowWelcomeScreen();
       return;
-    case QuickStartScreen::Result::WIFI_CONNECTED:
     case QuickStartScreen::Result::WIFI_CREDENTIALS_RECEIVED:
     case QuickStartScreen::Result::CANCEL_AND_RETURN_TO_NETWORK:
       ShowNetworkScreen();
diff --git a/chrome/browser/ash/login/wizard_controller.h b/chrome/browser/ash/login/wizard_controller.h
index 7e7f2307..3994b0d 100644
--- a/chrome/browser/ash/login/wizard_controller.h
+++ b/chrome/browser/ash/login/wizard_controller.h
@@ -50,7 +50,6 @@
 #include "chrome/browser/ash/login/screens/hardware_data_collection_screen.h"
 #include "chrome/browser/ash/login/screens/hid_detection_screen.h"
 #include "chrome/browser/ash/login/screens/kiosk_autolaunch_screen.h"
-#include "chrome/browser/ash/login/screens/local_password_setup_screen.h"
 #include "chrome/browser/ash/login/screens/locale_switch_screen.h"
 #include "chrome/browser/ash/login/screens/marketing_opt_in_screen.h"
 #include "chrome/browser/ash/login/screens/multidevice_setup_screen.h"
@@ -59,6 +58,7 @@
 #include "chrome/browser/ash/login/screens/online_authentication_screen.h"
 #include "chrome/browser/ash/login/screens/os_install_screen.h"
 #include "chrome/browser/ash/login/screens/os_trial_screen.h"
+#include "chrome/browser/ash/login/screens/osauth/local_password_setup_screen.h"
 #include "chrome/browser/ash/login/screens/packaged_license_screen.h"
 #include "chrome/browser/ash/login/screens/parental_handoff_screen.h"
 #include "chrome/browser/ash/login/screens/password_selection_screen.h"
diff --git a/chrome/browser/ash/ownership/owner_settings_service_ash.cc b/chrome/browser/ash/ownership/owner_settings_service_ash.cc
index bb6bb0f..2efa2c6 100644
--- a/chrome/browser/ash/ownership/owner_settings_service_ash.cc
+++ b/chrome/browser/ash/ownership/owner_settings_service_ash.cc
@@ -650,7 +650,6 @@
     //   kAccountsPrefEphemeralUsersEnabled
     //   kAccountsPrefFamilyLinkAccountsAllowed
     //   kAccountsPrefTransferSAMLCookies
-    //   kDeviceAttestationEnabled
     //   kDeviceOwner
     //   kDeviceReportRuntimeCounters
     //   kDeviceReportXDREvents
diff --git a/chrome/browser/ash/policy/core/device_policy_decoder.cc b/chrome/browser/ash/policy/core/device_policy_decoder.cc
index 5ce14530..61d3fd97 100644
--- a/chrome/browser/ash/policy/core/device_policy_decoder.cc
+++ b/chrome/browser/ash/policy/core/device_policy_decoder.cc
@@ -1685,13 +1685,6 @@
   }
 
   if (policy.has_attestation_settings()) {
-    if (policy.attestation_settings().has_attestation_enabled()) {
-      policies->Set(
-          key::kAttestationEnabledForDevice, POLICY_LEVEL_MANDATORY,
-          POLICY_SCOPE_MACHINE, POLICY_SOURCE_CLOUD,
-          base::Value(policy.attestation_settings().attestation_enabled()),
-          nullptr);
-    }
     if (policy.attestation_settings().has_content_protection_enabled()) {
       policies->Set(
           key::kAttestationForContentProtectionEnabled, POLICY_LEVEL_MANDATORY,
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer.cc
index 4f07c287..c6f34e84 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer.cc
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer.cc
@@ -11,8 +11,10 @@
 #include "ash/public/cpp/session/session_types.h"
 #include "ash/shell.h"
 #include "base/files/file_path.h"
+#include "base/functional/callback.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/sequence_checker.h"
 #include "base/task/sequenced_task_runner.h"
@@ -32,7 +34,7 @@
 
 using ::ash::cros_healthd::mojom::CrashEventInfo;
 using ::ash::cros_healthd::mojom::CrashEventInfoPtr;
-using ::ash::cros_healthd::mojom::CrashUploadInfoPtr;
+using ::ash::cros_healthd::mojom::EventInfoPtr;
 
 namespace {
 
@@ -40,7 +42,6 @@
     "/var/lib/reporting/crash_events/REPORTED_LOCAL_IDS";
 constexpr std::string_view kDefaultUploadedCrashInfoSaveFilePath =
     "/var/lib/reporting/crash_events/UPLOADED_CRASH_INFO";
-constexpr base::TimeDelta kDefaultBackoffTimeForLoading = base::Seconds(5);
 
 // Get current user session.
 const ash::UserSession* GetCurrentUserSession() {
@@ -90,19 +91,29 @@
     : FatalCrashEventsObserver(
           base::FilePath(kDefaultReportedLocalIdSaveFilePath),
           base::FilePath(kDefaultUploadedCrashInfoSaveFilePath),
-          kDefaultBackoffTimeForLoading) {}
+          /*reported_local_id_io_task_runner=*/nullptr) {}
 
 FatalCrashEventsObserver::FatalCrashEventsObserver(
     base::FilePath reported_local_id_save_file,
     base::FilePath uploaded_crash_info_save_file,
-    base::TimeDelta backoff_time_for_loading)
+    scoped_refptr<base::SequencedTaskRunner> reported_local_id_io_task_runner)
     : MojoServiceEventsObserverBase<ash::cros_healthd::mojom::EventObserver>(
           this),
       reported_local_id_manager_{ReportedLocalIdManager::Create(
-          std::move(reported_local_id_save_file))},
+          std::move(reported_local_id_save_file),
+          // Don't BindPostTask here, because it would risk calling
+          // `ProcessEventsBeforeSaveFilesLoaded` twice, once from
+          // reported_local_id_manager_, once from uploaded_crash_info_manager_
+          // (TODO(b/266018440): to be implemented).
+          /*save_file_loaded_callback=*/
+          base::BindOnce(
+              &FatalCrashEventsObserver::ProcessEventsBeforeSaveFilesLoaded,
+              // Called from member reported_local_id_manager_ from
+              // the same sequence, safe to assume this instance is still alive.
+              base::Unretained(this)),
+          std::move(reported_local_id_io_task_runner))},
       uploaded_crash_info_manager_{UploadedCrashInfoManager::Create(
-          std::move(uploaded_crash_info_save_file))},
-      backoff_time_for_loading_{backoff_time_for_loading} {}
+          std::move(uploaded_crash_info_save_file))} {}
 
 FatalCrashEventsObserver::~FatalCrashEventsObserver() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -131,24 +142,37 @@
   skipped_uploaded_callback_ = std::move(callback);
 }
 
-void FatalCrashEventsObserver::OnEvent(
-    ash::cros_healthd::mojom::EventInfoPtr info) {
+void FatalCrashEventsObserver::SetEventCollectedBeforeSaveFilesLoadedCallback(
+    EventCollectedBeforeSaveFilesLoadedCallback callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  event_collected_before_save_files_loaded_callback_ = std::move(callback);
+}
 
-  if (!AreLoaded()) {
-    // If save files are still being loaded, wait for
-    // `backoff_time_for_loading_` (5 seconds in production code).
-    base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
-        FROM_HERE,
-        base::BindOnce(&FatalCrashEventsObserver::OnEvent,
-                       weak_factory_.GetWeakPtr(), std::move(info)),
-        backoff_time_for_loading_);
-    return;
-  }
+void FatalCrashEventsObserver::OnEvent(EventInfoPtr info) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   if (!info->is_crash_event_info()) {
     return;
   }
+
+  // Events in `event_queue_before_save_files_loaded_` must be processed first.
+  // If the events there have not been cleared, enqueue this event there.
+  if (!AreSaveFilesLoaded() || !event_queue_before_save_files_loaded_.empty()) {
+    if (event_collected_before_save_files_loaded_callback_) {
+      event_collected_before_save_files_loaded_callback_.Run(
+          info->get_crash_event_info().Clone());
+    }
+    event_queue_before_save_files_loaded_.push(std::move(info));
+    return;
+  }
+
+  ProcessEvent(std::move(info));
+}
+
+void FatalCrashEventsObserver::ProcessEvent(EventInfoPtr info) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK(info->is_crash_event_info());
+
   const auto& crash_event_info = info->get_crash_event_info();
 
   if (crash_event_info->upload_info.is_null()) {
@@ -221,10 +245,43 @@
                          BindNewPipeAndPassRemote());
 }
 
-bool FatalCrashEventsObserver::AreLoaded() const {
+bool FatalCrashEventsObserver::AreSaveFilesLoaded() const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   // TODO(b/266018440): Also off-load uploaded_crash_info_manager_'s save file.
-  return reported_local_id_manager_->IsLoaded();
+  return reported_local_id_manager_->IsSaveFileLoaded();
+}
+
+void FatalCrashEventsObserver::ProcessEventsBeforeSaveFilesLoaded() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  if (!AreSaveFilesLoaded()) {
+    // Don't do anything if not yet loaded. There are two save files,
+    // REPORTED_LOCAL_IDS and UPLOADED_CRASH_INFO. This function is called when
+    // either save file is loaded(TODO(b/266018440): UPLOADED_CRASH_INFO to be
+    // implemented).
+    //
+    // The first call to this method would likely reach here as it is called
+    // when the first save file is loaded, since the other file is not yet
+    // loaded.
+    return;
+  }
+
+  if (event_queue_before_save_files_loaded_.empty()) {
+    return;
+  }
+
+  // Only crash events can be enqueued to `events_gathered_before_loaded_`.
+  CHECK(event_queue_before_save_files_loaded_.front()->is_crash_event_info());
+
+  ProcessEvent(std::move(event_queue_before_save_files_loaded_.front()));
+  event_queue_before_save_files_loaded_.pop();
+
+  // Process one crash event at a time to avoid blocking processing other types
+  // of events.
+  base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
+      FROM_HERE,
+      base::BindOnce(
+          &FatalCrashEventsObserver::ProcessEventsBeforeSaveFilesLoaded,
+          weak_factory_.GetWeakPtr()));
 }
 
 MetricData FatalCrashEventsObserver::FillFatalCrashTelemetry(
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer.h b/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer.h
index 5f4780f..13ed05cd 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer.h
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer.h
@@ -6,13 +6,17 @@
 #define CHROME_BROWSER_ASH_POLICY_REPORTING_METRICS_REPORTING_FATAL_CRASH_FATAL_CRASH_EVENTS_OBSERVER_H_
 
 #include <memory>
+#include <queue>
 #include <string>
 
 #include "base/files/file_path.h"
 #include "base/functional/callback.h"
 #include "base/functional/callback_helpers.h"
+#include "base/gtest_prod_util.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/time/time.h"
 #include "chrome/browser/ash/policy/reporting/metrics_reporting/mojo_service_events_observer_base.h"
 #include "chromeos/ash/services/cros_healthd/public/mojom/cros_healthd_events.mojom.h"
@@ -42,6 +46,9 @@
       base::RepeatingCallback<void(std::string /* crash_report_id */,
                                    base::Time /* creation_time */,
                                    uint64_t /* offset */)>;
+  using EventCollectedBeforeSaveFilesLoadedCallback =
+      base::RepeatingCallback<void(
+          ::ash::cros_healthd::mojom::CrashEventInfoPtr)>;
 
   // UMA name for recording the reason that an unuploaded crash should not be
   // reported.
@@ -67,11 +74,23 @@
   // Sets the callback that is called when an uploaded crash is skipped.
   void SetSkippedUploadedCrashCallback(SkippedUploadedCrashCallback callback);
 
+  // Sets the callback that is called when a crash is queued due to delayed save
+  // file loading.
+  void SetEventCollectedBeforeSaveFilesLoadedCallback(
+      EventCollectedBeforeSaveFilesLoadedCallback callback);
+
  private:
   // Give `TestEnvironment` the access to the private constructor that
   // specifies the path for the save file.
   friend class FatalCrashEventsObserver::TestEnvironment;
 
+  // For `OnEvent`. Not let `TestEnvironment` be a proxy of `OnEvent` because it
+  // is an exception to allow `SlowFileLoadingFieldsPassedThrough` to call
+  // `OnEvent` directly. Using `TestEnvironment` as a proxy would expose
+  // `OnEvent` to all tests and weaken access checks.
+  FRIEND_TEST_ALL_PREFIXES(FatalCrashEventsObserverTest,
+                           SlowFileLoadingFieldsPassedThrough);
+
   // Manages the local IDs corresponding to reported unuploaded crashes. Once
   // a crash is uploaded, it is outside the purview of this class.
   class ReportedLocalIdManager;
@@ -81,21 +100,31 @@
   class UploadedCrashInfoManager;
 
   FatalCrashEventsObserver();
+  // This constructor enables the test code to use non-default values of the
+  // input parameters to accommodate the test environment. In production code,
+  // they are always the default value specified in the default constructor.
   FatalCrashEventsObserver(base::FilePath reported_local_id_save_file,
                            base::FilePath uploaded_crash_info_save_file,
-                           base::TimeDelta backoff_time_for_loading);
+                           scoped_refptr<base::SequencedTaskRunner>
+                               reported_local_id_io_task_runner);
 
   MetricData FillFatalCrashTelemetry(
       const ::ash::cros_healthd::mojom::CrashEventInfoPtr& info);
 
   // ash::cros_healthd::mojom::EventObserver:
-  void OnEvent(const ash::cros_healthd::mojom::EventInfoPtr info) override;
+  void OnEvent(ash::cros_healthd::mojom::EventInfoPtr info) override;
 
   // CrosHealthdEventsObserverBase
   void AddObserver() override;
 
+  // Processes an event received via `OnEvent`.
+  void ProcessEvent(ash::cros_healthd::mojom::EventInfoPtr info);
+
   // Indicates whether the save files have been loaded.
-  bool AreLoaded() const;
+  bool AreSaveFilesLoaded() const;
+
+  // Processes events that was received before the save files have been loaded.
+  void ProcessEventsBeforeSaveFilesLoaded();
 
   // Sets whether to continue postprocessing after event observed callback is
   // called. Pass in true to simulate that event observed callback is
@@ -113,8 +142,15 @@
   std::unique_ptr<UploadedCrashInfoManager> uploaded_crash_info_manager_
       GUARDED_BY_CONTEXT(sequence_checker_);
 
-  // Called when an unuploaded crash is skipped and not reported. Currently
-  // only used in tests but production code may also use it in the future.
+  // Intermediate queue that tracks events received from croshealthd before save
+  // files are loaded. Recorded events are processed in the order that they are
+  // received once save files are loaded.
+  std::queue<ash::cros_healthd::mojom::EventInfoPtr>
+      event_queue_before_save_files_loaded_
+          GUARDED_BY_CONTEXT(sequence_checker_);
+
+  // Called when an unuploaded crash is skipped and not reported. Currently only
+  // used in tests but production code may also use it in the future.
   SkippedUnuploadedCrashCallback skipped_unuploaded_callback_
       GUARDED_BY_CONTEXT(sequence_checker_){base::DoNothing()};
 
@@ -123,13 +159,18 @@
   SkippedUploadedCrashCallback skipped_uploaded_callback_
       GUARDED_BY_CONTEXT(sequence_checker_){base::DoNothing()};
 
+  // Called when a crash event is queued due to a delayed save file loading.
+  // Currently only used in tests but production code may also use it in the
+  // future.
+  EventCollectedBeforeSaveFilesLoadedCallback
+      event_collected_before_save_files_loaded_callback_
+          GUARDED_BY_CONTEXT(sequence_checker_);
+
   // If true, stop the processing after the event observed callback is called.
   // Only used for testing.
   bool interrupted_after_event_observed_for_test_
       GUARDED_BY_CONTEXT(sequence_checker_){false};
 
-  const base::TimeDelta backoff_time_for_loading_;
-
   base::WeakPtrFactory<FatalCrashEventsObserver> weak_factory_{this};
 };
 }  // namespace reporting
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_reported_local_id_manager.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_reported_local_id_manager.cc
index 96c734e..eae85fa 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_reported_local_id_manager.cc
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_reported_local_id_manager.cc
@@ -11,9 +11,12 @@
 #include <string>
 #include <utility>
 
+#include "base/check.h"
 #include "base/containers/contains.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
+#include "base/functional/callback.h"
+#include "base/functional/callback_helpers.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/sequence_checker.h"
@@ -21,12 +24,21 @@
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/task/task_runner.h"
+#include "base/task/thread_pool.h"
 
 namespace reporting {
 
 FatalCrashEventsObserver::ReportedLocalIdManager::ReportedLocalIdManager(
-    base::FilePath save_file_path)
-    : save_file_{std::move(save_file_path)} {
+    base::FilePath save_file_path,
+    SaveFileLoadedCallback save_file_loaded_callback,
+    scoped_refptr<base::SequencedTaskRunner> io_task_runner)
+    : save_file_{std::move(save_file_path)},
+      save_file_loaded_callback_{std::move(save_file_loaded_callback)},
+      io_task_runner_{io_task_runner == nullptr
+                          ? base::ThreadPool::CreateSequencedTaskRunner(
+                                {base::TaskShutdownBehavior::BLOCK_SHUTDOWN,
+                                 base::MayBlock()})
+                          : std::move(io_task_runner)} {
   LoadSaveFile();
 }
 
@@ -37,9 +49,12 @@
 // static
 std::unique_ptr<FatalCrashEventsObserver::ReportedLocalIdManager>
 FatalCrashEventsObserver::ReportedLocalIdManager::Create(
-    base::FilePath save_file_path) {
-  return base::WrapUnique(
-      new ReportedLocalIdManager(std::move(save_file_path)));
+    base::FilePath save_file_path,
+    SaveFileLoadedCallback save_file_loaded_callback,
+    scoped_refptr<base::SequencedTaskRunner> io_task_runner) {
+  return base::WrapUnique(new ReportedLocalIdManager(
+      std::move(save_file_path), std::move(save_file_loaded_callback),
+      io_task_runner));
 }
 
 bool FatalCrashEventsObserver::ReportedLocalIdManager::HasBeenReported(
@@ -156,11 +171,14 @@
 void FatalCrashEventsObserver::ReportedLocalIdManager::ResumeLoadingSaveFile(
     const std::string& content) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK(save_file_loaded_callback_);
 
-  // It is OK to set loaded_ at the beginning of this method, because all future
-  // tasks in this sequence would see the save file has been loaded. Setting at
-  // the front avoids repeating this statement before every return.
-  loaded_ = true;
+  base::ScopedClosureRunner run_callback_on_return(base::BindOnce(
+      [](bool* save_file_loaded, SaveFileLoadedCallback callback) {
+        *save_file_loaded = true;
+        std::move(callback).Run();
+      },
+      &save_file_loaded_, std::move(save_file_loaded_callback_)));
 
   // Parse the CSV file line by line. If one line is erroneous, stop parsing the
   // rest.
@@ -284,9 +302,10 @@
   local_id_entry_queue_.pop();
 }
 
-bool FatalCrashEventsObserver::ReportedLocalIdManager::IsLoaded() const {
+bool FatalCrashEventsObserver::ReportedLocalIdManager::IsSaveFileLoaded()
+    const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return loaded_;
+  return save_file_loaded_;
 }
 
 bool FatalCrashEventsObserver::ReportedLocalIdManager::LocalIdEntryComparator::
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_reported_local_id_manager.h b/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_reported_local_id_manager.h
index d3b9bd3..c91a51b4 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_reported_local_id_manager.h
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_reported_local_id_manager.h
@@ -11,11 +11,11 @@
 #include <unordered_map>
 
 #include "base/files/file_path.h"
+#include "base/functional/callback.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
 #include "base/task/sequenced_task_runner.h"
-#include "base/task/thread_pool.h"
 #include "chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer.h"
 #include "chromeos/ash/services/cros_healthd/public/mojom/cros_healthd_events.mojom.h"
 
@@ -23,6 +23,9 @@
 
 class FatalCrashEventsObserver::ReportedLocalIdManager {
  public:
+  // Callback type once the save file is loaded.
+  using SaveFileLoadedCallback = base::OnceCallback<void()>;
+
   // The result of `ShouldReport`.
   enum class ShouldReportResult : uint8_t {
     kYes = 0u,
@@ -32,8 +35,19 @@
     kMaxValue = kCrashTooOldAndMaxNumOfSavedLocalIdsReached
   };
 
+  // Create a `ReportedLocalIdManager` instance.
+  //
+  // Params:
+  //
+  // - save_file_path: Path to the save file.
+  // - save_file_loaded_callback: The value of `save_file_loaded_callback_`. See
+  // - its document.
+  // - io_task_runner: The task runner to run IO tasks on. If nullptr, the
+  //                   constructor would create a default task runner.
   static std::unique_ptr<ReportedLocalIdManager> Create(
-      base::FilePath save_file_path);
+      base::FilePath save_file_path,
+      SaveFileLoadedCallback save_file_loaded_callback,
+      scoped_refptr<base::SequencedTaskRunner> io_task_runner);
   ReportedLocalIdManager(const ReportedLocalIdManager&) = delete;
   ReportedLocalIdManager& operator=(const ReportedLocalIdManager&) = delete;
   virtual ~ReportedLocalIdManager();
@@ -71,7 +85,7 @@
   void Remove(const std::string& local_id);
 
   // Indicates whether the save file has been loaded.
-  bool IsLoaded() const;
+  bool IsSaveFileLoaded() const;
 
  private:
   // Give `TestEnvironment` the access to `kMaxNumOfLocalIds`.
@@ -93,7 +107,10 @@
   // The maximum size of the priority queue before reconstructing it.
   static constexpr size_t kMaxSizeOfLocalIdEntryQueue{kMaxNumOfLocalIds * 10u};
 
-  explicit ReportedLocalIdManager(base::FilePath save_file_path);
+  ReportedLocalIdManager(
+      base::FilePath save_file_path,
+      SaveFileLoadedCallback save_file_loaded_callback,
+      scoped_refptr<base::SequencedTaskRunner> io_task_runner);
 
   // Loads save file. Logs and ignores errors. If there is a parsing error,
   // still loads all lines before the line on which the error occurs. Does not
@@ -153,14 +170,19 @@
                       LocalIdEntryComparator>
       local_id_entry_queue_ GUARDED_BY_CONTEXT(sequence_checker_);
 
+  // Indicates whether loading has finished.
+  bool save_file_loaded_ GUARDED_BY_CONTEXT(sequence_checker_){false};
+
+  // Called when the save file is loaded. Should only be called once because the
+  // save file is only loaded once throughout the lifetime of this class
+  // instance.
+  SaveFileLoadedCallback save_file_loaded_callback_
+      GUARDED_BY_CONTEXT(sequence_checker_);
+
   // The task runner that performs IO. This instance would not be recreated in
   // production code, but may be in unit tests.
-  scoped_refptr<base::SequencedTaskRunner> io_task_runner_ GUARDED_BY_CONTEXT(
-      sequence_checker_){base::ThreadPool::CreateSequencedTaskRunner(
-      {base::TaskShutdownBehavior::BLOCK_SHUTDOWN, base::MayBlock()})};
-
-  // Indicates whether loading has finished.
-  bool loaded_ GUARDED_BY_CONTEXT(sequence_checker_){false};
+  const scoped_refptr<base::SequencedTaskRunner> io_task_runner_
+      GUARDED_BY_CONTEXT(sequence_checker_);
 
   base::WeakPtrFactory<ReportedLocalIdManager> weak_factory_{this};
 };
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_test_util.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_test_util.cc
index fd81398..a0e6873 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_test_util.cc
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_test_util.cc
@@ -7,10 +7,12 @@
 #include <memory>
 
 #include "base/files/file_path.h"
-#include "base/functional/callback_helpers.h"
+#include "base/functional/bind.h"
 #include "base/memory/ptr_util.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/run_loop.h"
 #include "base/sequence_checker.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/time/time.h"
 #include "chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer.h"
 #include "chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_reported_local_id_manager.h"
@@ -22,12 +24,21 @@
 FatalCrashEventsObserver::TestEnvironment::~TestEnvironment() = default;
 
 std::unique_ptr<FatalCrashEventsObserver>
-FatalCrashEventsObserver::TestEnvironment::CreateFatalCrashEventsObserver()
+FatalCrashEventsObserver::TestEnvironment::CreateFatalCrashEventsObserver(
+    scoped_refptr<base::SequencedTaskRunner> reported_local_id_io_task_runner)
     const {
   auto observer = base::WrapUnique(new FatalCrashEventsObserver(
       GetReportedLocalIdSaveFilePath(), GetUploadedCrashInfoSaveFilePath(),
-      // Don't delay any tasks in unit tests.
-      /*backoff_time_for_loading=*/base::TimeDelta()));
+      reported_local_id_io_task_runner));
+
+  if (reported_local_id_io_task_runner == nullptr) {
+    // For most tests, we focus on the behavior after save files are loaded.
+    // Thus, make sure IO is completed to prevent flaky tests.
+    FlushIoTasks(*observer);
+  }
+
+  // Clear tasks such as registering the observer.
+  base::RunLoop().RunUntilIdle();
   return observer;
 }
 
@@ -67,10 +78,40 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(
       observer.reported_local_id_manager_->sequence_checker_);
 
+  // Block the main thread while flushing IO tasks. Not using `PostTaskAndReply`
+  // on QuitClosure because the QuitClosure task must be posted first before the
+  // main thread can be unblocked to prevent race.
+  SequenceBlocker sequence_blocker(
+      base::SequencedTaskRunner::GetCurrentDefault());
   base::RunLoop run_loop;
-  observer.reported_local_id_manager_->io_task_runner_->PostTaskAndReply(
-      FROM_HERE, base::DoNothing(), run_loop.QuitClosure());
+  observer.reported_local_id_manager_->io_task_runner_->PostTask(
+      FROM_HERE,
+      base::BindOnce(
+          [](scoped_refptr<base::SequencedTaskRunner> main_task_runner,
+             SequenceBlocker* sequence_blocker,
+             base::RepeatingClosure quit_closure) {
+            main_task_runner->PostTask(FROM_HERE, std::move(quit_closure));
+            sequence_blocker->Unblock();
+          },
+          base::SequencedTaskRunner::GetCurrentDefault(),
+          // Safe to pass the address of sequence_blocker because run_loop.Run()
+          // below will clear the task posted by the blocker.
+          base::Unretained(&sequence_blocker), run_loop.QuitClosure()));
   run_loop.Run();
 }
 
+FatalCrashEventsObserver::TestEnvironment::SequenceBlocker::SequenceBlocker(
+    scoped_refptr<base::SequencedTaskRunner> task_runner) {
+  task_runner->PostTask(FROM_HERE, base::BindOnce(
+                                       [](std::atomic<bool>* blocked) {
+                                         while (blocked->load()) {
+                                           // Wait...
+                                         }
+                                       },
+                                       &blocked_));
+}
+
+void FatalCrashEventsObserver::TestEnvironment::SequenceBlocker::Unblock() {
+  blocked_ = false;
+}
 }  // namespace reporting
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_test_util.h b/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_test_util.h
index 3f5cf43..3abad2a 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_test_util.h
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_test_util.h
@@ -9,6 +9,8 @@
 #include <string_view>
 
 #include "base/files/file_path.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/task/sequenced_task_runner.h"
 #include "base/test/test_file_util.h"
 #include "chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer.h"
 #include "chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_reported_local_id_manager.h"
@@ -21,6 +23,21 @@
   using ShouldReportResult =
       FatalCrashEventsObserver::ReportedLocalIdManager::ShouldReportResult;
 
+  // Posts a task that blocks a sequence, and unblocks when requested. User must
+  // ensure that the blocking task is cleared when this object is destroyed.
+  class SequenceBlocker {
+   public:
+    explicit SequenceBlocker(
+        scoped_refptr<base::SequencedTaskRunner> task_runner);
+
+    SequenceBlocker(const SequenceBlocker&) = delete;
+    SequenceBlocker& operator=(const SequenceBlocker&) = delete;
+
+    void Unblock();
+
+   private:
+    std::atomic<bool> blocked_{true};
+  };
   static constexpr size_t kMaxNumOfLocalIds{
       ReportedLocalIdManager::kMaxNumOfLocalIds};
   static constexpr size_t kMaxSizeOfLocalIdEntryQueue{
@@ -42,9 +59,13 @@
   const base::FilePath& GetUploadedCrashInfoSaveFilePath() const;
 
   // Creates a `FatalCrashEventsObserver` object that uses `save_file_path_` as
-  // the save file and returns the pointer.
-  std::unique_ptr<FatalCrashEventsObserver> CreateFatalCrashEventsObserver()
-      const;
+  // the save file and returns the pointer. If
+  // `reported_local_id_io_task_runner` is not null, use it as the io task
+  // runner and do not flush IO tasks (i.e., leave the control of the task
+  // runner to the caller).
+  std::unique_ptr<FatalCrashEventsObserver> CreateFatalCrashEventsObserver(
+      scoped_refptr<base::SequencedTaskRunner>
+          reported_local_id_io_task_runner = nullptr) const;
 
   // Sets whether to continue postprocessing after event observed callback is
   // called.
@@ -59,7 +80,9 @@
   // usage is correctly limited.
   static size_t GetLocalIdEntryQueueSize(FatalCrashEventsObserver& observer);
 
-  // Flushes all IO tasks.
+  // Flushes all IO tasks. Also post a blocking task to the calling thread to
+  // prevent the calling thread to move forward beyond the current tasks in
+  // queue. Unblock the calling thread once the IO tasks are flushed.
   static void FlushIoTasks(FatalCrashEventsObserver& observer);
 
  private:
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_unittest.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_unittest.cc
index 7479b5b8..192e112 100644
--- a/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_unittest.cc
+++ b/chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_unittest.cc
@@ -6,18 +6,22 @@
 #include "chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_reported_local_id_manager.h"
 #include "chrome/browser/ash/policy/reporting/metrics_reporting/fatal_crash/fatal_crash_events_observer_uploaded_crash_info_manager.h"
 
+#include <atomic>
 #include <memory>
 #include <sstream>
 #include <string>
 #include <string_view>
 #include <tuple>
 #include <utility>
+#include <vector>
 
 #include "ash/test/ash_test_base.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/task/thread_pool.h"
 #include "base/test/bind.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/test_file_util.h"
@@ -34,7 +38,6 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace reporting {
-namespace {
 
 using std::literals::string_view_literals::operator""sv;
 
@@ -44,7 +47,10 @@
 using ::ash::cros_healthd::mojom::CrashUploadInfo;
 using ::ash::cros_healthd::mojom::EventCategoryEnum;
 using ::ash::cros_healthd::mojom::EventInfo;
+using ::testing::Eq;
+using ::testing::SizeIs;
 
+namespace {
 // RAII class to interrupt after event is observed.
 class ScopedInterruptedAfterEventObserved {
  public:
@@ -77,6 +83,8 @@
   raw_ptr<FatalCrashEventsObserver> observer_;
 };
 
+}  // namespace
+
 // Base class for testing `FatalCrashEventsObserver`. `NoSessionAshTestBase` is
 // needed here because the observer uses `ash::Shell()` to obtain the user
 // session type.
@@ -384,6 +392,124 @@
   }
 }
 
+TEST_P(FatalCrashEventsObserverTest, SlowFileLoadingFieldsPassedThrough) {
+  // Test that fields are passed through for crash events that either:
+  //   1. come before save files are loaded, or
+  //   2. before all crashes queued before save files are loaded.
+
+  // Because FakeCrosHealthd::Get()->EmitEventForCategory() causes tasks on the
+  // current thread to be processed, for this test alone, we call
+  // FatalCrashEventsObserver::OnEvent directly to emulate the effect of
+  // FakeCrosHealthd::Get()->EmitEventForCategory().
+
+  if (is_uploaded()) {
+    GTEST_SKIP() << "Slow file loading for uploaded crashes will be added once "
+                    "its IO offloading is done";
+  }
+
+  // Need 4 crash events to work around limitations in manipulating tasks in a
+  // sequence.
+  static constexpr size_t kNumCrashes = 4;
+  static constexpr std::array<std::string_view, kNumCrashes> kLocalIds = {
+      "First local ID", "Second local ID", "Third Local ID", "Fourth Local ID"};
+
+  std::array<CrashEventInfoPtr, kNumCrashes> crash_event_infos = {
+      NewCrashEventInfo(/*is_uploaded=*/is_uploaded()),
+      NewCrashEventInfo(/*is_uploaded=*/is_uploaded()),
+      NewCrashEventInfo(/*is_uploaded=*/is_uploaded()),
+      NewCrashEventInfo(/*is_uploaded=*/is_uploaded())};
+  for (size_t i = 0; i < crash_event_infos.size(); ++i) {
+    // Test the local ID field sufficient.
+    crash_event_infos[i]->local_id = kLocalIds[i];
+  }
+
+  const auto io_task_runner = base::ThreadPool::CreateSequencedTaskRunner(
+      {base::TaskShutdownBehavior::BLOCK_SHUTDOWN, base::MayBlock()});
+
+  // Block the IO thread.
+  FatalCrashEventsObserver::TestEnvironment::SequenceBlocker sequence_blocker(
+      io_task_runner);
+
+  // Create and set up the observer object.
+  auto observer = fatal_crash_test_environment_.CreateFatalCrashEventsObserver(
+      /*reported_local_id_io_task_runner=*/io_task_runner);
+  observer->SetReportingEnabled(true);
+  // Not using `TestFuture`, because it can only accept one value at a time and
+  // generates an error if another values comes in before the first value is
+  // taken. Due to the racing of the task sequence in unit tests, pushing
+  // results to a vector would not be flaky.
+  std::vector<MetricData> results;
+  results.reserve(4u);
+  observer->SetOnEventObservedCallback(base::BindRepeating(
+      [](std::vector<MetricData>* results,
+         scoped_refptr<base::SequencedTaskRunner> main_task_runner,
+         MetricData metric_data) {
+        ASSERT_THAT(base::SequencedTaskRunner::GetCurrentDefault(),
+                    Eq(main_task_runner));
+        results->push_back(std::move(metric_data));
+      },
+      &results, base::SequencedTaskRunner::GetCurrentDefault()));
+  base::test::TestFuture<CrashEventInfoPtr> queued_crash_event_result;
+  observer->SetEventCollectedBeforeSaveFilesLoadedCallback(
+      queued_crash_event_result.GetRepeatingCallback());
+
+  // Emit the first 3 events before the save file is loaded. The event is
+  // queued and saved in RAM.
+  for (size_t i = 0; i < 3u; ++i) {
+    base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
+        FROM_HERE, base::BindOnce(&FatalCrashEventsObserver::OnEvent,
+                                  observer->weak_factory_.GetWeakPtr(),
+                                  EventInfo::NewCrashEventInfo(
+                                      std::move(crash_event_infos[i]))));
+    // Sanity check to ensure that the crash event is indeed queued.
+    EXPECT_THAT(queued_crash_event_result.Take()->local_id, Eq(kLocalIds[i]));
+  }
+
+  // Unblock the IO, flush the IO (thus save files are loaded), and emit the
+  // fourth event. Because the third event has not been processed yet when
+  // `OnEvent` for the fourth event is called, the fourth event is also expected
+  // to be queued up.
+  ASSERT_TRUE(!observer->AreSaveFilesLoaded())
+      << "Internal error: Save files are loaded even task thread is blocked";
+  sequence_blocker.Unblock();
+  FatalCrashEventsObserver::TestEnvironment::FlushIoTasks(*observer);
+  ASSERT_TRUE(observer->AreSaveFilesLoaded())
+      << "Internal error: Flushing IO tasks does not finish loading save files";
+  base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
+      FROM_HERE, base::BindOnce(&FatalCrashEventsObserver::OnEvent,
+                                observer->weak_factory_.GetWeakPtr(),
+                                EventInfo::NewCrashEventInfo(
+                                    std::move(crash_event_infos[3]))));
+  // Flushing IO tasks causes the first ProcessEventsBeforeSaveFilesLoaded task
+  // (which has filled result_metric_data) executed and the second
+  // ProcessEventsBeforeSaveFilesLoaded task left in the sequence. Therefore,
+  // the current sequence contains the second ProcessEventsBeforeSaveFilesLoaded
+  // task followed by one OnEvent task.
+  // Sanity check to ensure that the crash event is indeed queued.
+  EXPECT_THAT(queued_crash_event_result.Take()->local_id, Eq(kLocalIds[3]));
+
+  // All crash events should be available in order, and the event collected call
+  // back should never be called from this point on.
+  observer->SetEventCollectedBeforeSaveFilesLoadedCallback(
+      base::BindRepeating([](CrashEventInfoPtr crash_event_info) {
+        // Sanity check to ensure that no more crash event is queued.
+        EXPECT_FALSE(true) << "Found unexpected queued crash event: "
+                           << crash_event_info->local_id;
+      }));
+  base::RunLoop().RunUntilIdle();
+  ASSERT_THAT(results, SizeIs(4u));
+  for (size_t i = 0; i < results.size(); ++i) {
+    const auto& metric_data = results[i];
+    ASSERT_TRUE(metric_data.has_telemetry_data());
+    ASSERT_TRUE(metric_data.telemetry_data().has_fatal_crash_telemetry());
+    const auto& fatal_crash_telemetry =
+        metric_data.telemetry_data().fatal_crash_telemetry();
+
+    ASSERT_TRUE(fatal_crash_telemetry.has_local_id());
+    EXPECT_EQ(fatal_crash_telemetry.local_id(), kLocalIds[i]);
+  }
+}
+
 INSTANTIATE_TEST_SUITE_P(
     FatalCrashEventsObserverTests,
     FatalCrashEventsObserverTest,
@@ -1554,6 +1680,4 @@
     [](const testing::TestParamInfo<
         FatalCrashEventsObserverUploadedCrashCorruptSaveFileTest::ParamType>&
            info) { return info.param.name; });
-
-}  // namespace
 }  // namespace reporting
diff --git a/chrome/browser/ash/settings/device_settings_provider.cc b/chrome/browser/ash/settings/device_settings_provider.cc
index 5fd810d..dfa94a6 100644
--- a/chrome/browser/ash/settings/device_settings_provider.cc
+++ b/chrome/browser/ash/settings/device_settings_provider.cc
@@ -76,7 +76,6 @@
     kDeviceActivityHeartbeatCollectionRateMs,
     kDeviceActivityHeartbeatEnabled,
     kDeviceAllowedBluetoothServices,
-    kDeviceAttestationEnabled,
     kDeviceAutoUpdateTimeRestrictions,
     kDeviceCrostiniArcAdbSideloadingAllowed,
     kDeviceDisabled,
@@ -949,10 +948,6 @@
                                 policy.variations_parameter().parameter());
   }
 
-  new_values_cache->SetBoolean(
-      kDeviceAttestationEnabled,
-      policy.attestation_settings().attestation_enabled());
-
   if (policy.has_attestation_settings() &&
       policy.attestation_settings().has_content_protection_enabled()) {
     new_values_cache->SetBoolean(
diff --git a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_time_of_day_browsertest.cc b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_time_of_day_browsertest.cc
index 9d15178..197db893 100644
--- a/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_time_of_day_browsertest.cc
+++ b/chrome/browser/ash/system_web_apps/apps/personalization_app/personalization_app_time_of_day_browsertest.cc
@@ -112,8 +112,11 @@
       public testing::WithParamInterface<TimeOfDayTestParams> {
  public:
   PersonalizationAppTimeOfDayBrowserTest() {
-    scoped_feature_list_.InitWithFeatures(
-        personalization_app::GetTimeOfDayEnabledFeatures(), {});
+    std::vector<base::test::FeatureRef> enabled_features =
+        personalization_app::GetTimeOfDayEnabledFeatures();
+    enabled_features.emplace_back(
+        features::kTimeOfDayWallpaperForcedAutoSchedule);
+    scoped_feature_list_.InitWithFeatures(enabled_features, {});
     base::Time start_time = StartTime();
     clock_.SetNow(start_time);
     tick_clock_.SetNowTicks(base::TimeTicks() + (start_time - base::Time()));
diff --git a/chrome/browser/autofill/mock_autofill_popup_controller.h b/chrome/browser/autofill/mock_autofill_popup_controller.h
index c6bac732..6d0ded0 100644
--- a/chrome/browser/autofill/mock_autofill_popup_controller.h
+++ b/chrome/browser/autofill/mock_autofill_popup_controller.h
@@ -109,7 +109,8 @@
       // Accessibility requires all focusable AutofillPopupItemView to have
       // ui::AXNodeData with non-empty names. We specify dummy values and labels
       // to satisfy this.
-      suggestions_.emplace_back("dummy_value", "dummy_label", "", id);
+      suggestions_.emplace_back("dummy_value", "dummy_label",
+                                Suggestion::Icon::kNoIcon, id);
     }
   }
 
diff --git a/chrome/browser/bookmarks/chrome_bookmark_client.cc b/chrome/browser/bookmarks/chrome_bookmark_client.cc
index 9c1fe23..3eb34dc 100644
--- a/chrome/browser/bookmarks/chrome_bookmark_client.cc
+++ b/chrome/browser/bookmarks/chrome_bookmark_client.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/bookmarks/chrome_bookmark_client.h"
 
+#include "base/metrics/histogram_functions.h"
 #include "base/metrics/user_metrics.h"
 #include "base/notreached.h"
 #include "base/time/time.h"
@@ -15,6 +16,7 @@
 #include "components/bookmarks/browser/bookmark_model.h"
 #include "components/bookmarks/browser/bookmark_node.h"
 #include "components/bookmarks/browser/bookmark_storage.h"
+#include "components/bookmarks/common/bookmark_pref_names.h"
 #include "components/bookmarks/managed/managed_bookmark_service.h"
 #include "components/bookmarks/managed/managed_bookmark_util.h"
 #include "components/commerce/core/commerce_feature_list.h"
@@ -88,7 +90,12 @@
       local_or_syncable_bookmark_sync_service_(
           local_or_syncable_bookmark_sync_service),
       account_bookmark_sync_service_(account_bookmark_sync_service),
-      bookmark_undo_service_(bookmark_undo_service) {}
+      bookmark_undo_service_(bookmark_undo_service) {
+  CHECK(profile_);
+  base::UmaHistogramBoolean(
+      "Bookmarks.BookmarkBar.Shown",
+      profile_->GetPrefs()->GetBoolean(bookmarks::prefs::kShowBookmarkBar));
+}
 
 ChromeBookmarkClient::~ChromeBookmarkClient() {
   if (shopping_save_location_provider_) {
diff --git a/chrome/browser/device_reauth/chromeos/authenticator_chromeos.cc b/chrome/browser/device_reauth/chromeos/authenticator_chromeos.cc
index 58f13b2..d3f3ee54 100644
--- a/chrome/browser/device_reauth/chromeos/authenticator_chromeos.cc
+++ b/chrome/browser/device_reauth/chromeos/authenticator_chromeos.cc
@@ -11,7 +11,7 @@
 #include "chromeos/ash/components/osauth/public/common_types.h"
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
-#include "chromeos/crosapi/mojom/in_session_auth.mojom.h"
+#include "chromeos/components/in_session_auth/mojom/in_session_auth.mojom.h"
 #include "chromeos/lacros/lacros_service.h"
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
 
@@ -30,11 +30,12 @@
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
 void OnRequestToken(base::OnceCallback<void(bool)> callback,
-                    crosapi::mojom::RequestTokenReplyPtr reply) {
+                    chromeos::auth::mojom::RequestTokenReplyPtr reply) {
   // Similarly to `OnAuthComplete`, we ignore the token provided in reply, if
   // any.
   std::move(callback).Run(
-      reply != mojo::StructPtr<crosapi::mojom::RequestTokenReply>(nullptr));
+      reply !=
+      mojo::StructPtr<chromeos::auth::mojom::RequestTokenReply>(nullptr));
 }
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
 
@@ -48,10 +49,10 @@
     base::OnceCallback<void(bool)> result_callback) {
   // Calls `InSessionAuthDialogController::ShowAuthDialog` to authenticate the
   // currently active user using configured auth factors.
-  // On Lacros, makes a crosapi call to the `mojom::InSessionAuth` interface
-  // implemented by ash in crosapi::InSessionAuthAsh. This in turn calls
-  // `InSessionAuthDialogController::ShowAuthDialog` to authenticate the
-  // currently active user using configured auth factors.
+  // On Lacros, makes a crosapi call to the
+  // `chromeos::auth::mojom::InSessionAuth` interface implemented by ash. This
+  // in turn calls `InSessionAuthDialogController::ShowAuthDialog` to
+  // authenticate the currently active user using configured auth factors.
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   ash::InSessionAuthDialogController::Get()->ShowAuthDialog(
@@ -59,17 +60,22 @@
       base::BindOnce(&OnAuthComplete, std::move(result_callback)));
 #elif BUILDFLAG(IS_CHROMEOS_LACROS)
   if (auto* lacros_service = chromeos::LacrosService::Get();
-      lacros_service->IsAvailable<crosapi::mojom::InSessionAuth>()) {
-    if (lacros_service->GetInterfaceVersion<crosapi::mojom::InSessionAuth>() <
-        static_cast<int>(crosapi::mojom::InSessionAuth::MethodMinVersions::
-                             kRequestTokenMinVersion)) {
-      lacros_service->GetRemote<crosapi::mojom::InSessionAuth>()->RequestToken(
-          crosapi::mojom::Reason::kAccessPasswordManager, absl::nullopt,
-          base::BindOnce(&OnRequestToken, std::move(result_callback)));
+      lacros_service->IsAvailable<chromeos::auth::mojom::InSessionAuth>()) {
+    if (lacros_service
+            ->GetInterfaceVersion<chromeos::auth::mojom::InSessionAuth>() <
+        static_cast<int>(chromeos::auth::mojom::InSessionAuth::
+                             MethodMinVersions::kRequestTokenMinVersion)) {
+      lacros_service->GetRemote<chromeos::auth::mojom::InSessionAuth>()
+          ->RequestToken(
+              chromeos::auth::mojom::Reason::kAccessPasswordManager,
+              absl::nullopt,
+              base::BindOnce(&OnRequestToken, std::move(result_callback)));
     } else {
-      lacros_service->GetRemote<crosapi::mojom::InSessionAuth>()->RequestToken(
-          crosapi::mojom::Reason::kAccessPasswordManager, std::string(),
-          base::BindOnce(&OnRequestToken, std::move(result_callback)));
+      lacros_service->GetRemote<chromeos::auth::mojom::InSessionAuth>()
+          ->RequestToken(
+              chromeos::auth::mojom::Reason::kAccessPasswordManager,
+              std::string(),
+              base::BindOnce(&OnRequestToken, std::move(result_callback)));
     }
   }
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/browser/devtools/chrome_devtools_manager_delegate.cc b/chrome/browser/devtools/chrome_devtools_manager_delegate.cc
index 7c398874..2aa72fc 100644
--- a/chrome/browser/devtools/chrome_devtools_manager_delegate.cc
+++ b/chrome/browser/devtools/chrome_devtools_manager_delegate.cc
@@ -105,6 +105,13 @@
     *type = ChromeDevToolsManagerDelegate::kTypePage;
     return true;
   }
+
+  // Set type to other for component views such as virtual keyboard.
+  if (view_type == extensions::mojom::ViewType::kComponent) {
+    *type = DevToolsAgentHost::kTypeOther;
+    return true;
+  }
+
   return false;
 }
 
diff --git a/chrome/browser/enterprise/data_controls/dlp_reporting_manager.cc b/chrome/browser/enterprise/data_controls/dlp_reporting_manager.cc
index 82b682ba..8f9a697 100644
--- a/chrome/browser/enterprise/data_controls/dlp_reporting_manager.cc
+++ b/chrome/browser/enterprise/data_controls/dlp_reporting_manager.cc
@@ -355,6 +355,11 @@
                      "functionality will be disabled.";
     return;
   }
+
+  for (auto& observer : observers_) {
+    observer.OnReportEvent(event);
+  }
+
   reporting::ReportQueue::EnqueueCallback callback = base::BindOnce(
       &DlpReportingManager::OnEventEnqueued, weak_factory_.GetWeakPtr());
 
@@ -392,4 +397,12 @@
   VLOG(1) << "DLP event sent to reporting infrastructure.";
 }
 
+void DlpReportingManager::AddObserver(Observer* observer) {
+  observers_.AddObserver(observer);
+}
+
+void DlpReportingManager::RemoveObserver(Observer* observer) {
+  observers_.RemoveObserver(observer);
+}
+
 }  // namespace data_controls
diff --git a/chrome/browser/enterprise/data_controls/dlp_reporting_manager.h b/chrome/browser/enterprise/data_controls/dlp_reporting_manager.h
index ed9a9087..0253886 100644
--- a/chrome/browser/enterprise/data_controls/dlp_reporting_manager.h
+++ b/chrome/browser/enterprise/data_controls/dlp_reporting_manager.h
@@ -7,11 +7,12 @@
 
 #include <memory>
 
+#include "base/observer_list.h"
 #include "base/task/sequenced_task_runner.h"
+#include "build/chromeos_buildflags.h"
 #include "components/enterprise/data_controls/dlp_policy_event.pb.h"
 #include "components/enterprise/data_controls/rule.h"
 #include "components/reporting/client/report_queue.h"
-#include "build/chromeos_buildflags.h"
 #include "components/reporting/util/status.h"
 
 class DlpPolicyEvent;
@@ -96,6 +97,13 @@
   using ReportQueueSetterCallback =
       base::OnceCallback<void(std::unique_ptr<reporting::ReportQueue>)>;
 
+  // For callers who are interested in observing DLP reporting events.
+  class Observer : public base::CheckedObserver {
+   public:
+    // Invoked whenever a new event is being reported.
+    virtual void OnReportEvent(DlpPolicyEvent event) = 0;
+  };
+
   DlpReportingManager();
   DlpReportingManager(const DlpReportingManager&) = delete;
   ~DlpReportingManager();
@@ -141,6 +149,9 @@
       std::unique_ptr<::reporting::ReportQueue, base::OnTaskRunnerDeleter>
           report_queue);
 
+  void AddObserver(Observer* observer);
+  void RemoveObserver(Observer* observer);
+
  private:
   void OnEventEnqueued(reporting::Status status);
 
@@ -150,6 +161,8 @@
   std::unique_ptr<::reporting::ReportQueue, base::OnTaskRunnerDeleter>
       report_queue_;
 
+  base::ObserverList<Observer> observers_;
+
   base::WeakPtrFactory<DlpReportingManager> weak_factory_{this};
 };
 }  // namespace data_controls
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn
index b3693f8..8084b63 100644
--- a/chrome/browser/extensions/BUILD.gn
+++ b/chrome/browser/extensions/BUILD.gn
@@ -994,7 +994,10 @@
   ]
 
   if (enable_supervised_users) {
-    deps += [ "//components/supervised_user/core/browser" ]
+    deps += [
+      "//components/supervised_user/core/browser",
+      "//components/supervised_user/core/browser:supervised_user_preferences",
+    ]
   }
 
   if (is_linux || is_mac || is_win) {
diff --git a/chrome/browser/extensions/api/file_system/request_file_system_notification.cc b/chrome/browser/extensions/api/file_system/request_file_system_notification.cc
index f93abf4..5bca2416 100644
--- a/chrome/browser/extensions/api/file_system/request_file_system_notification.cc
+++ b/chrome/browser/extensions/api/file_system/request_file_system_notification.cc
@@ -61,6 +61,7 @@
   void OnAppImageUpdated(
       const std::string& id,
       const gfx::ImageSkia& image,
+      bool is_placeholder_icon,
       const absl::optional<gfx::ImageSkia>& badge_image) override {
     pending_notification_->set_icon(ui::ImageModel::FromImageSkia(image));
     auto* notification_display_service =
diff --git a/chrome/browser/extensions/api/passwords_private/password_check_delegate_unittest.cc b/chrome/browser/extensions/api/passwords_private/password_check_delegate_unittest.cc
index 85dfc814..c442f85 100644
--- a/chrome/browser/extensions/api/passwords_private/password_check_delegate_unittest.cc
+++ b/chrome/browser/extensions/api/passwords_private/password_check_delegate_unittest.cc
@@ -959,8 +959,8 @@
   delegate().StartPasswordCheck();
   EXPECT_EQ(events::PASSWORDS_PRIVATE_ON_PASSWORD_CHECK_STATUS_CHANGED,
             event_iter->second->histogram_value);
-  auto status = PasswordCheckStatus::FromValueDeprecated(
-      event_iter->second->event_args.front());
+  auto status =
+      PasswordCheckStatus::FromValue(event_iter->second->event_args.front());
   EXPECT_EQ(api::passwords_private::PasswordCheckState::kRunning,
             status->state);
   EXPECT_EQ(0, *status->already_processed);
@@ -969,8 +969,8 @@
   static_cast<BulkLeakCheckDelegateInterface*>(service())->OnFinishedCredential(
       LeakCheckCredential(kUsername1, kPassword1), IsLeaked(false));
 
-  status = PasswordCheckStatus::FromValueDeprecated(
-      event_iter->second->event_args.front());
+  status =
+      PasswordCheckStatus::FromValue(event_iter->second->event_args.front());
   EXPECT_EQ(api::passwords_private::PasswordCheckState::kRunning,
             status->state);
   EXPECT_EQ(2, *status->already_processed);
@@ -979,8 +979,8 @@
   static_cast<BulkLeakCheckDelegateInterface*>(service())->OnFinishedCredential(
       LeakCheckCredential(kUsername2, kPassword2), IsLeaked(false));
 
-  status = PasswordCheckStatus::FromValueDeprecated(
-      event_iter->second->event_args.front());
+  status =
+      PasswordCheckStatus::FromValue(event_iter->second->event_args.front());
   EXPECT_EQ(api::passwords_private::PasswordCheckState::kRunning,
             status->state);
   EXPECT_EQ(4, *status->already_processed);
diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
index e1300d2..c7b3432 100644
--- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc
+++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -6127,8 +6127,8 @@
 }
 
 // Tests that an MV3 extension can use the `webRequestAuthProvider` permission
-// to intercept and handle `onAuthRequired` events.
-IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest, TestOnAuthRequired) {
+// to intercept and handle `onAuthRequired` events coming from a tab.
+IN_PROC_BROWSER_TEST_F(ManifestV3WebRequestApiTest, TestOnAuthRequiredTab) {
   CancelLoginDialog login_dialog_helper;
   ASSERT_TRUE(StartEmbeddedTestServer());
 
@@ -6182,6 +6182,144 @@
   EXPECT_TRUE(navigation_observer.last_navigation_succeeded());
 }
 
+class OnAuthRequiredApiTest : public ExtensionApiTest {
+ public:
+  static constexpr char kTestDomain[] = "a.test";
+  OnAuthRequiredApiTest() {
+    // Https is required to use service workers.
+    // This limits the set of domains with valid certificates. For the purposes
+    // of this test we will use kTestDomain.
+    UseHttpsTestServer();
+  }
+  ~OnAuthRequiredApiTest() override = default;
+
+  void SetUpOnMainThread() override {
+    ExtensionApiTest::SetUpOnMainThread();
+    host_resolver()->AddRule("*", "127.0.0.1");
+
+    embedded_test_server()->ServeFilesFromSourceDirectory("chrome/test/data");
+    ASSERT_TRUE(StartEmbeddedTestServer());
+  }
+
+  // Returns a URL which requires username/password
+  GURL MakeAuthUrl() {
+    static constexpr char kRealm[] = "mv3authprovider";
+    std::string auth_url_path =
+        base::StringPrintf("/auth-basic/%s/subpath?realm=%s", kRealm, kRealm);
+    return embedded_test_server()->GetURL(kTestDomain, auth_url_path);
+  }
+
+  // Loads an extension that implements onAuthRequired. `additional_js` will be
+  // concatenated to the background.js.
+  void LoadExtensionWithAdditionalJs(const std::string& additional_js) {
+    static constexpr char kManifest[] =
+        R"({
+             "name": "MV3 WebRequest",
+             "version": "0.1",
+             "manifest_version": 3,
+             "permissions": ["webRequest", "webRequestAuthProvider"],
+             "host_permissions": [ "http://127.0.0.1/*", "https://a.test/*" ],
+             "background": {"service_worker": "background.js"}
+           })";
+    static constexpr char kBackgroundJs[] =
+        R"(
+            let didInterceptAuth = false;
+            chrome.webRequest.onAuthRequired.addListener(
+               (details, callback) => {
+                 didInterceptAuth = true;
+                 chrome.test.assertEq('mv3authprovider', details.realm);
+                 chrome.test.assertEq(401, details.statusCode);
+                 const authCredentials = {username: 'foo', password: 'secret'};
+                 callback({authCredentials});
+               },
+               {urls: ['<all_urls>']},
+               ['asyncBlocking']);
+          )";
+    std::string background_js(kBackgroundJs);
+    background_js += additional_js;
+
+    test_extension_dir_.WriteManifest(kManifest);
+    test_extension_dir_.WriteFile(FILE_PATH_LITERAL("background.js"),
+                                  background_js);
+
+    const Extension* extension =
+        LoadExtension(test_extension_dir_.UnpackedPath());
+    ASSERT_TRUE(extension);
+  }
+
+ private:
+  TestExtensionDir test_extension_dir_;
+  base::ScopedTempDir service_worker_dir_;
+};
+
+// Tests that an MV3 extension can use the `webRequestAuthProvider` permission
+// to intercept and handle `onAuthRequired` events coming from an extension
+// service worker. This test does the following:
+//   (1) This loads an extension with a service-worker background.js.
+//   (2) The extension adds a listener to chrome.webRequest.onAuthRequired.
+//   (3) The extension attempts to fetch a resource that requires http auth.
+//   (4) This triggers the listener in (3), which supplies credentials
+//   (5) Checks that the fetch succeeded.
+IN_PROC_BROWSER_TEST_F(OnAuthRequiredApiTest,
+                       TestOnAuthRequiredExtensionServiceWorker) {
+  // If the login dialog is shown, it is immediately rejected causing the test
+  // to fail rather than hang indefinitely.
+  CancelLoginDialog login_dialog_helper;
+
+  // After the extension loads, trigger an async request to fetch an http auth
+  // resource.
+  std::string additional_js =
+      R"(
+          (async function() {
+            try {
+              const response = await fetch($1);
+              if (response.ok) {
+                 chrome.test.assertTrue(didInterceptAuth);
+              } else {
+                 chrome.test.fail();
+              }
+            } catch (e) {
+              chrome.test.fail();
+            }
+          })();
+        )";
+  additional_js = content::JsReplace(additional_js, MakeAuthUrl());
+
+  // Loading the extension triggers the remaining steps of the test.
+  ResultCatcher result_catcher;
+  LoadExtensionWithAdditionalJs(additional_js);
+
+  // TODO(https://crbug.com/1371177): When the bug is fixed, this should become
+  // an ASSERT_TRUE.
+  ASSERT_FALSE(result_catcher.GetNextResult());
+}
+
+// This test is similar to TestOnAuthRequiredExtensionServiceWorker but the
+// service worker is hosted by a website instead of the extension istelf.
+IN_PROC_BROWSER_TEST_F(OnAuthRequiredApiTest,
+                       TestOnAuthRequiredWebsiteServiceWorker) {
+  CancelLoginDialog login_dialog_helper;
+
+  // Load the extension.
+  LoadExtensionWithAdditionalJs("");
+
+  // Navigate to the test page.
+  GURL requestor_url = embedded_test_server()->GetURL(
+      kTestDomain, "/ssl/service_worker_fetch/page.html");
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), requestor_url));
+
+  // Perform a fetch from a worker and validate that it succeeds.
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  std::string fetch_response =
+      content::EvalJs(web_contents,
+                      content::JsReplace("doFetchInWorker($1);", MakeAuthUrl()))
+          .ExtractString();
+  // TODO(https://crbug.com/1371177): When the bug is fixed, this should become
+  // an EXPECT_THAT with a different value.
+  EXPECT_THAT(fetch_response, testing::HasSubstr("Denied"));
+}
+
 // Tests the behavior of an extension that registers an event listener
 // asynchronously.
 // Regression test for https://crbug.com/1397879 and https://crbug.com/1434212.
diff --git a/chrome/browser/extensions/chrome_app_icon_loader.cc b/chrome/browser/extensions/chrome_app_icon_loader.cc
index 2108b80..74a087c 100644
--- a/chrome/browser/extensions/chrome_app_icon_loader.cc
+++ b/chrome/browser/extensions/chrome_app_icon_loader.cc
@@ -91,6 +91,7 @@
 
 void ChromeAppIconLoader::OnIconUpdated(ChromeAppIcon* icon) {
   delegate()->OnAppImageUpdated(icon->app_id(), icon->image_skia(),
+                                /*is_placeholder_icon=*/false,
                                 /*badge_image=*/absl::nullopt);
 }
 
diff --git a/chrome/browser/extensions/chrome_app_icon_unittest.cc b/chrome/browser/extensions/chrome_app_icon_unittest.cc
index 8fa058f6..93b1e09 100644
--- a/chrome/browser/extensions/chrome_app_icon_unittest.cc
+++ b/chrome/browser/extensions/chrome_app_icon_unittest.cc
@@ -116,6 +116,7 @@
   void OnAppImageUpdated(
       const std::string& app_id,
       const gfx::ImageSkia& image,
+      bool is_placeholder_icon,
       const absl::optional<gfx::ImageSkia>& badge_image) override {
     image_skia_ = image;
   }
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index b2eed6b..20b1627 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -131,8 +131,7 @@
 #endif
 
 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
-#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
-#include "components/supervised_user/core/browser/supervised_user_service.h"
+#include "components/supervised_user/core/browser/supervised_user_preferences.h"
 #endif  // BUILDFLAG(ENABLE_SUPERVISED_USERS)
 
 using content::BrowserContext;
@@ -1318,12 +1317,10 @@
 
     // If this profile is not supervised, then remove any supervised user
     // related disable reasons.
-    bool is_supervised;
+    bool is_supervised = false;
 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
-    is_supervised = SupervisedUserServiceFactory::GetForProfile(profile())
-                        ->IsSubjectToParentalControls();
-#else
-    is_supervised = false;
+    is_supervised =
+        profile() && supervised_user::IsChildAccount(*profile()->GetPrefs());
 #endif
     if (!is_supervised) {
       disable_reasons &= (~disable_reason::DISABLE_CUSTODIAN_APPROVAL_REQUIRED);
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 905ba5c..10ea036c 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -852,11 +852,6 @@
     "expiry_milestone": 111
   },
   {
-    "name": "bluetooth-wbs-dogfood",
-    "owners": [ "hychao@chromium.org" ],
-    "expiry_milestone": 95
-  },
-  {
     "name": "bookmarks-improved-save-flow",
     "owners": ["wylieb@chromium.org", "fgorski@chromium.org", "mdjones@chromium.org"],
     "expiry_milestone": 115
@@ -1372,12 +1367,12 @@
   {
     "name": "cros-privacy-hub-app-permissions",
     "owners": [ "cros-privacy-features-dev@google.com" ],
-    "expiry_milestone": 124
+    "expiry_milestone": 128
   },
   {
     "name": "cros-privacy-hub-v0",
     "owners": [ "chromeos-privacyhub@google.com" ],
-    "expiry_milestone": 120
+    "expiry_milestone": 124
   },
   {
     "name": "cros-shortstand",
@@ -2323,7 +2318,7 @@
   {
     "name": "enable-cros-privacy-hub",
     "owners": [ "chromeos-privacyhub@google.com" ],
-    "expiry_milestone": 120
+    "expiry_milestone": 128
   },
   {
     "name": "enable-cros-system-japanese-physical-typing",
@@ -7621,6 +7616,11 @@
     "expiry_milestone": 120
   },
   {
+    "name": "time-of-day-wallpaper-forced-auto-schedule",
+    "owners": [ "esum@chromium.org", "jasontt@chromium.org", "assistive-eng@google.com" ],
+    "expiry_milestone": 124
+  },
+  {
     "name": "tint-composited-content",
     "owners": [ "chromeos-gfx@google.com" ],
     // This flag is used for QA & development on ChromeOS, which has no way to
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 5479c22..512098fa 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -5649,14 +5649,6 @@
     "which will send the Bluetooth link quality statistics such as the "
     "signal strength, the lost packet count, etc. to the host.";
 
-const char kBluetoothWbsDogfoodName[] = "Bluetooth WBS dogfood";
-const char kBluetoothWbsDogfoodDescription[] =
-    "Enables Bluetooth wideband speech mic as default audio option. "
-    "Note that flipping this flag makes no difference on most of the "
-    "ChromeOS models, because Bluetooth WBS is either unsupported "
-    "or fully launched. Only on the few models that Bluetooth WBS is "
-    "still stablizing this flag will take effect.";
-
 const char kBluetoothCoredumpName[] = "Enable Bluetooth Device Coredump";
 const char kBluetoothCoredumpDescription[] =
     "Enable Bluetooth coredump collection if supported. Please note that "
@@ -7019,6 +7011,13 @@
 const char kTimeOfDayWallpaperDescription[] =
     "Enables Time of Day Wallpaper feature on supported devices.";
 
+const char kTimeOfDayWallpaperForcedAutoScheduleName[] =
+    "Time of Day Wallpaper Forced Auto Schedule";
+const char kTimeOfDayWallpaperForcedAutoScheduleDescription[] =
+    "Forces the time of day wallpaper to change on an automatic "
+    "sunset-to-sunrise schedule, regardless of what dark/light mode settings "
+    "are active. Not used if time of day wallpaper is not enabled.";
+
 const char kTimeOfDayDlcName[] = "Time of Day Dlc";
 const char kTimeOfDayDlcDescription[] =
     "Enables downloading Time of Day Screen Saver assets from DLC rather than "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 299e86b..1327c1a 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -3267,9 +3267,6 @@
 extern const char kBluetoothQualityReportName[];
 extern const char kBluetoothQualityReportDescription[];
 
-extern const char kBluetoothWbsDogfoodName[];
-extern const char kBluetoothWbsDogfoodDescription[];
-
 extern const char kBluetoothCoredumpName[];
 extern const char kBluetoothCoredumpDescription[];
 
@@ -4031,6 +4028,9 @@
 extern const char kTimeOfDayWallpaperName[];
 extern const char kTimeOfDayWallpaperDescription[];
 
+extern const char kTimeOfDayWallpaperForcedAutoScheduleName[];
+extern const char kTimeOfDayWallpaperForcedAutoScheduleDescription[];
+
 extern const char kTimeOfDayDlcName[];
 extern const char kTimeOfDayDlcDescription[];
 
diff --git a/chrome/browser/hid/hid_chooser_context.cc b/chrome/browser/hid/hid_chooser_context.cc
index d9a8346..c68ca3c5 100644
--- a/chrome/browser/hid/hid_chooser_context.cc
+++ b/chrome/browser/hid/hid_chooser_context.cc
@@ -7,6 +7,8 @@
 #include <utility>
 
 #include "base/containers/contains.h"
+#include "base/containers/cxx20_erase_set.h"
+#include "base/containers/map_util.h"
 #include "base/observer_list.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
@@ -431,23 +433,24 @@
     const url::Origin& origin,
     const device::mojom::HidDeviceInfo& device) {
   auto it = ephemeral_devices_.find(origin);
-  if (it != ephemeral_devices_.end()) {
-    std::set<std::string>& devices = it->second;
-    for (auto guid = devices.begin(); guid != devices.end();) {
-      auto device_it = devices_.find(*guid);
-      if (device_it == devices_.end()) {
-        continue;
-      }
-      if (device_it->second->physical_device_id != device.physical_device_id) {
-        ++guid;
-        continue;
-      }
+  if (it == ephemeral_devices_.end()) {
+    return;
+  }
 
-      guid = devices.erase(guid);
-      if (devices.empty())
-        ephemeral_devices_.erase(it);
-      NotifyPermissionRevoked(origin);
-    }
+  std::set<std::string>& device_guids = it->second;
+  bool revoked_permission =
+      base::EraseIf(device_guids, [&](const auto& guid) {
+        auto* device_ptr = base::FindPtrOrNull(devices_, guid);
+        return device_ptr &&
+               device_ptr->physical_device_id == device.physical_device_id;
+      }) > 0;
+
+  if (device_guids.empty()) {
+    ephemeral_devices_.erase(it);
+  }
+
+  if (revoked_permission) {
+    NotifyPermissionRevoked(origin);
   }
 }
 
diff --git a/chrome/browser/hid/hid_chooser_context_unittest.cc b/chrome/browser/hid/hid_chooser_context_unittest.cc
index 74b0b55..e069f81 100644
--- a/chrome/browser/hid/hid_chooser_context_unittest.cc
+++ b/chrome/browser/hid/hid_chooser_context_unittest.cc
@@ -52,7 +52,8 @@
 constexpr uint16_t kTestProductId = 0xabcd;
 constexpr char kTestSerialNumber[] = "serial-number";
 constexpr char kTestProductName[] = "product-name";
-constexpr char kTestPhysicalDeviceId[] = "physical-device-id";
+const char* const kTestPhysicalDeviceIds[] = {"physical-device-id-1",
+                                              "physical-device-id-2"};
 constexpr char kTestUserEmail[] = "user@example.com";
 
 // The HID usages assigned to the top-level collection of the simulated device.
@@ -126,7 +127,8 @@
   MockHidDeviceObserver& device_observer() { return device_observer_; }
 
   device::mojom::HidDeviceInfoPtr CreateDevice(
-      base::StringPiece serial_number) {
+      base::StringPiece serial_number,
+      const std::string& physical_device_id = kTestPhysicalDeviceIds[0]) {
     auto collection = device::mojom::HidCollectionInfo::New();
     collection->usage =
         device::mojom::HidUsageAndPage::New(kTestUsage, kTestUsagePage);
@@ -136,7 +138,7 @@
 
     auto device = device::mojom::HidDeviceInfo::New();
     device->guid = base::Uuid::GenerateRandomV4().AsLowercaseString();
-    device->physical_device_id = kTestPhysicalDeviceId;
+    device->physical_device_id = physical_device_id;
     device->vendor_id = kTestVendorId;
     device->product_id = kTestProductId;
     device->product_name = kTestProductName;
@@ -381,16 +383,12 @@
 
   // Forget the ephemeral device.
   base::RunLoop permissions_revoked_loop;
-  auto permissions_revoked_barrier =
-      base::BarrierClosure(2, permissions_revoked_loop.QuitClosure());
   EXPECT_CALL(permission_observer(), OnPermissionRevoked(kOrigin))
-      .Times(2)
-      .WillRepeatedly(RunClosure(permissions_revoked_barrier));
+      .WillOnce(RunClosure(permissions_revoked_loop.QuitClosure()));
   EXPECT_CALL(permission_observer(),
               OnObjectPermissionChanged(
                   absl::make_optional(ContentSettingsType::HID_GUARD),
-                  ContentSettingsType::HID_CHOOSER_DATA))
-      .Times(2);
+                  ContentSettingsType::HID_CHOOSER_DATA));
   context()->RevokeDevicePermission(kOrigin, *device1);
   permissions_revoked_loop.Run();
 
@@ -400,6 +398,44 @@
   EXPECT_EQ(0u, context()->GetAllGrantedObjects().size());
 }
 
+TEST_F(HidChooserContextTest, GrantTwoEphemeralDevicesForgetOne) {
+  const auto kOrigin = url::Origin::Create(GURL("https://google.com"));
+
+  // Connect two devices that are only eligible for ephemeral permissions.
+  auto device1 = ConnectDeviceBlocking(CreateDevice(
+      /*serial_number=*/"", /*physical_device_id=*/kTestPhysicalDeviceIds[0]));
+  auto device2 = ConnectDeviceBlocking(CreateDevice(
+      /*serial_number=*/"", /*physical_device_id=*/kTestPhysicalDeviceIds[1]));
+  EXPECT_FALSE(context()->HasDevicePermission(kOrigin, *device1));
+  EXPECT_FALSE(context()->HasDevicePermission(kOrigin, *device2));
+  EXPECT_EQ(0u, context()->GetGrantedObjects(kOrigin).size());
+  EXPECT_EQ(0u, context()->GetAllGrantedObjects().size());
+
+  // Grant ephemeral permissions.
+  GrantDevicePermissionBlocking(kOrigin, *device1);
+  GrantDevicePermissionBlocking(kOrigin, *device2);
+  EXPECT_TRUE(context()->HasDevicePermission(kOrigin, *device1));
+  EXPECT_TRUE(context()->HasDevicePermission(kOrigin, *device2));
+  EXPECT_EQ(2u, context()->GetGrantedObjects(kOrigin).size());
+  EXPECT_EQ(2u, context()->GetAllGrantedObjects().size());
+
+  // Forget the first device.
+  base::RunLoop permissions_revoked_loop;
+  EXPECT_CALL(permission_observer(), OnPermissionRevoked(kOrigin))
+      .WillOnce(RunClosure(permissions_revoked_loop.QuitClosure()));
+  EXPECT_CALL(permission_observer(),
+              OnObjectPermissionChanged(
+                  absl::make_optional(ContentSettingsType::HID_GUARD),
+                  ContentSettingsType::HID_CHOOSER_DATA));
+  context()->RevokeDevicePermission(kOrigin, *device1);
+  permissions_revoked_loop.Run();
+
+  EXPECT_FALSE(context()->HasDevicePermission(kOrigin, *device1));
+  EXPECT_TRUE(context()->HasDevicePermission(kOrigin, *device2));
+  EXPECT_EQ(1u, context()->GetGrantedObjects(kOrigin).size());
+  EXPECT_EQ(1u, context()->GetAllGrantedObjects().size());
+}
+
 TEST_F(HidChooserContextTest, GrantAndDisconnectEphemeralDevice) {
   const auto kOrigin = url::Origin::Create(GURL("https://google.com"));
 
diff --git a/chrome/browser/notifications/extension_notifier_controller.cc b/chrome/browser/notifications/extension_notifier_controller.cc
index 3292b49..62ba48a 100644
--- a/chrome/browser/notifications/extension_notifier_controller.cc
+++ b/chrome/browser/notifications/extension_notifier_controller.cc
@@ -78,6 +78,7 @@
 void ExtensionNotifierController::OnAppImageUpdated(
     const std::string& id,
     const gfx::ImageSkia& image,
+    bool is_placeholder_icon,
     const absl::optional<gfx::ImageSkia>& badge_image) {
   observer_->OnIconImageUpdated(
       message_center::NotifierId(message_center::NotifierType::APPLICATION, id),
diff --git a/chrome/browser/notifications/extension_notifier_controller.h b/chrome/browser/notifications/extension_notifier_controller.h
index 7e74f61..ec52165 100644
--- a/chrome/browser/notifications/extension_notifier_controller.h
+++ b/chrome/browser/notifications/extension_notifier_controller.h
@@ -30,6 +30,7 @@
   void OnAppImageUpdated(
       const std::string& id,
       const gfx::ImageSkia& image,
+      bool is_placeholder_icon,
       const absl::optional<gfx::ImageSkia>& badge_image) override;
 
   std::unique_ptr<AppIconLoader> app_icon_loader_;
diff --git a/chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer.cc
index 59050bb..1719680 100644
--- a/chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer.cc
@@ -177,11 +177,16 @@
 }
 
 void LcpCriticalPathPredictorPageLoadMetricsObserver::SetLcpElementLocator(
-    const std::string& lcp_element_locator) {
+    const std::string& lcp_element_locator,
+    bool lcp_timing_was_predicted) {
   if (!lcpp_data_inputs_) {
     lcpp_data_inputs_.emplace();
   }
   lcpp_data_inputs_->lcp_element_locator = lcp_element_locator;
+  // At most one element can be predicted.
+  // TODO(crbug.com/1493255): Check below condition.
+  // CHECK(!lcp_timing_was_predicted_ || !lcp_timing_was_predicted);
+  lcp_timing_was_predicted_ |= lcp_timing_was_predicted;
 }
 
 void LcpCriticalPathPredictorPageLoadMetricsObserver::AppendFetchedFontUrl(
@@ -219,9 +224,7 @@
   if (!hint || !hint->lcp_element_locators.size()) {
     return;
   }
-  // Predicted the most frequent LCP would be next LCP and record the
-  // actual result. see PredictLcpElementLocators() for the `hint` contents.
-  const bool predicted =
-      (hint->lcp_element_locators[0] == lcpp_data_inputs_->lcp_element_locator);
-  base::UmaHistogramBoolean(internal::kHistogramLCPPPredictSuccess, predicted);
+
+  base::UmaHistogramBoolean(internal::kHistogramLCPPPredictSuccess,
+                            lcp_timing_was_predicted_);
 }
diff --git a/chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer.h
index 94f621d0..2572b42 100644
--- a/chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer.h
+++ b/chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer.h
@@ -55,7 +55,8 @@
       const LcpCriticalPathPredictorPageLoadMetricsObserver&) = delete;
   ~LcpCriticalPathPredictorPageLoadMetricsObserver() override;
 
-  void SetLcpElementLocator(const std::string& lcp_element_locator);
+  void SetLcpElementLocator(const std::string& lcp_element_locator,
+                            bool is_predicted);
   void SetLcpInfluencerScriptUrls(
       const std::vector<GURL>& lcp_influencer_scripts);
   // Append fetched font URLs to the list to be passed to LCPP.
@@ -94,6 +95,10 @@
 
   absl::optional<predictors::LcppDataInputs> lcpp_data_inputs_;
 
+  // True iff one of `lcp_element_locator` via SetLcpElementLocator was
+  // predicted as true LCP.
+  bool lcp_timing_was_predicted_ = false;
+
   base::WeakPtrFactory<LcpCriticalPathPredictorPageLoadMetricsObserver>
       weak_factory_{this};
 };
diff --git a/chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer_unittest.cc
index d5cd422..15cd298a9 100644
--- a/chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/lcp_critical_path_predictor_page_load_metrics_observer_unittest.cc
@@ -94,10 +94,12 @@
     hint.lcp_element_locators = {"foo"};
     navigation->GetNavigationHandle()->SetLCPPNavigationHint(hint);
   }
-  void SetMockLcpElementLocator(
-      GURL url,
-      const std::string& mock_element_locator = "foo") {
-    lcpp_observers_[url]->SetLcpElementLocator(mock_element_locator);
+
+  void SetMockLcpElementLocator(GURL url,
+                                const std::string& mock_element_locator = "foo",
+                                bool is_predicted = false) {
+    lcpp_observers_[url]->SetLcpElementLocator(mock_element_locator,
+                                               is_predicted);
   }
 
   void ConfirmResult(GURL url,
@@ -175,6 +177,28 @@
                   /*learn_lcpp=*/false, /*record_uma=*/activate);
   }
 
+  void TestLCPPrediction(bool is_predicted) {
+    const GURL main_frame_url("https://test.example");
+    // Let predictor learn pseudo("lcp_previous") LCP locator
+    predictors::ResourcePrefetchPredictor* predictor =
+        predictors::LoadingPredictorFactory::GetForProfile(
+            Profile::FromBrowserContext(web_contents()->GetBrowserContext()))
+            ->resource_prefetch_predictor();
+    CHECK(predictor);
+    predictors::LcppDataInputs lcpp_data_inputs;
+    lcpp_data_inputs.lcp_element_locator = "lcp_previous";
+    predictor->LearnLcpp(main_frame_url.host(), lcpp_data_inputs);
+
+    // Predict LCP with the learned result.
+    NavigationWithLCPPHint(main_frame_url, /*provide_lcpp_hint=*/true);
+    SetMockLcpElementLocator(main_frame_url, "lcp_actual", is_predicted);
+    tester()->NavigateToUntrackedUrl();
+    // Result only depends `is_predicted` parameter.
+    EXPECT_THAT(tester()->histogram_tester().GetAllSamples(
+                    internal::kHistogramLCPPPredictSuccess),
+                base::BucketsAre(base::Bucket(is_predicted, 1)));
+  }
+
   page_load_metrics::mojom::PageLoadTiming timing_;
   std::map<GURL, LcpCriticalPathPredictorPageLoadMetricsObserver*>
       lcpp_observers_;
@@ -201,40 +225,9 @@
 }
 
 TEST_F(LcpCriticalPathPredictorPageLoadMetricsObserverTest, PredictLCPSuccess) {
-  const GURL main_frame_url("https://test.example");
-  const bool provide_lcpp_hint = true;
-  // Navigate main and reload to learn lcpp.
-  NavigationWithLCPPHint(main_frame_url, provide_lcpp_hint);
-  SetMockLcpElementLocator(main_frame_url);
-  // Predict LCP with the learned result.
-  NavigationWithLCPPHint(main_frame_url, provide_lcpp_hint);
-  SetMockLcpElementLocator(main_frame_url);
-  tester()->NavigateToUntrackedUrl();
-  // Expect hit.
-  EXPECT_THAT(tester()->histogram_tester().GetAllSamples(
-                  internal::kHistogramLCPPPredictSuccess),
-              base::BucketsAre(base::Bucket(true, 1)));
+  TestLCPPrediction(/*is_predicted=*/true);
 }
 
 TEST_F(LcpCriticalPathPredictorPageLoadMetricsObserverTest, PredictLCPFailed) {
-  const GURL main_frame_url("https://test.example");
-  // Let predictor learn pseudo("lcp_previous") LCP locator different from
-  // "actual" LCP locator (which is also pseudo or "lcp_actual" in test BTW.)
-  predictors::ResourcePrefetchPredictor* predictor =
-      predictors::LoadingPredictorFactory::GetForProfile(
-          Profile::FromBrowserContext(web_contents()->GetBrowserContext()))
-          ->resource_prefetch_predictor();
-  CHECK(predictor);
-  predictors::LcppDataInputs lcpp_data_inputs;
-  lcpp_data_inputs.lcp_element_locator = "lcp_previous";
-  predictor->LearnLcpp(main_frame_url.host(), lcpp_data_inputs);
-
-  // Predict LCP with the learned result.
-  NavigationWithLCPPHint(main_frame_url, /*provide_lcpp_hint=*/true);
-  SetMockLcpElementLocator(main_frame_url, "lcp_actual");
-  tester()->NavigateToUntrackedUrl();
-  // Expect failed.
-  EXPECT_THAT(tester()->histogram_tester().GetAllSamples(
-                  internal::kHistogramLCPPPredictSuccess),
-              base::BucketsAre(base::Bucket(false, 1)));
+  TestLCPPrediction(/*is_predicted=*/false);
 }
diff --git a/chrome/browser/password_manager/BUILD.gn b/chrome/browser/password_manager/BUILD.gn
index 41ac4ed5..583ce2f 100644
--- a/chrome/browser/password_manager/BUILD.gn
+++ b/chrome/browser/password_manager/BUILD.gn
@@ -10,9 +10,15 @@
 }
 
 source_set("backend_factory") {
+  sources = [
+    "password_store_backend_factory.cc",
+    "password_store_backend_factory.h",
+  ]
+
   deps = [
     ":password_manager_buildflags",
     "//components/password_manager/core/browser",
+    "//components/password_manager/core/browser/affiliation:affiliation_fetching",
     "//components/password_manager/core/common:common",
     "//components/prefs",
   ]
@@ -22,11 +28,6 @@
       "//components/webauthn/android",
     ]
   }
-
-  sources = [
-    "password_store_backend_factory.cc",
-    "password_store_backend_factory.h",
-  ]
 }
 
 buildflag_header("password_manager_buildflags") {
diff --git a/chrome/browser/password_manager/android/BUILD.gn b/chrome/browser/password_manager/android/BUILD.gn
index 8c42609..0ad1d7a 100644
--- a/chrome/browser/password_manager/android/BUILD.gn
+++ b/chrome/browser/password_manager/android/BUILD.gn
@@ -97,6 +97,7 @@
     "//components/password_manager/core/browser:password_form",
     "//components/password_manager/core/browser:unified_password_manager_proto",
     "//components/password_manager/core/browser/affiliation",
+    "//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:features",
@@ -501,6 +502,7 @@
     "//components/password_manager/content/browser:test_support",
     "//components/password_manager/core/browser",
     "//components/password_manager/core/browser:test_support",
+    "//components/password_manager/core/browser/affiliation:affiliation_fetching",
     "//components/password_manager/core/browser/features:password_features",
     "//components/password_manager/core/common",
     "//components/safe_browsing/core/browser/password_protection:test_support",
diff --git a/chrome/browser/password_manager/android/password_store_android_backend.cc b/chrome/browser/password_manager/android/password_store_android_backend.cc
index 889052e0..a4f1431 100644
--- a/chrome/browser/password_manager/android/password_store_android_backend.cc
+++ b/chrome/browser/password_manager/android/password_store_android_backend.cc
@@ -35,6 +35,7 @@
 #include "components/autofill/core/common/autofill_regexes.h"
 #include "components/password_manager/core/browser/affiliation/affiliated_match_helper.h"
 #include "components/password_manager/core/browser/affiliation/affiliation_utils.h"
+#include "components/password_manager/core/browser/affiliation/affiliations_prefetcher.h"
 #include "components/password_manager/core/browser/features/password_features.h"
 #include "components/password_manager/core/browser/password_form.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
@@ -549,9 +550,12 @@
   return operation_;
 }
 
-PasswordStoreAndroidBackend::PasswordStoreAndroidBackend(PrefService* prefs)
+PasswordStoreAndroidBackend::PasswordStoreAndroidBackend(
+    PrefService* prefs,
+    AffiliationsPrefetcher* affiliations_prefetcher)
     : lifecycle_helper_(std::make_unique<PasswordManagerLifecycleHelperImpl>()),
-      bridge_helper_(PasswordStoreAndroidBackendBridgeHelper::Create()) {
+      bridge_helper_(PasswordStoreAndroidBackendBridgeHelper::Create()),
+      affiliations_prefetcher_(affiliations_prefetcher) {
   DCHECK(bridge_helper_);
   prefs_ = prefs;
   DCHECK(prefs_);
@@ -569,10 +573,12 @@
     std::unique_ptr<PasswordManagerLifecycleHelper> lifecycle_helper,
     std::unique_ptr<PasswordSyncControllerDelegateAndroid>
         sync_controller_delegate,
-    PrefService* prefs)
+    PrefService* prefs,
+    AffiliationsPrefetcher* affiliations_prefetcher)
     : lifecycle_helper_(std::move(lifecycle_helper)),
       bridge_helper_(std::move(bridge_helper)),
-      sync_controller_delegate_(std::move(sync_controller_delegate)) {
+      sync_controller_delegate_(std::move(sync_controller_delegate)),
+      affiliations_prefetcher_(affiliations_prefetcher) {
   DCHECK(bridge_helper_);
   prefs_ = prefs;
   DCHECK(prefs_);
@@ -865,6 +871,15 @@
   }
   sync_service_ = sync_service;
   sync_controller_delegate_->OnSyncServiceInitialized(sync_service);
+
+  // Stop fetching affiliations if AndroidBackend can be used and branding info
+  // can be obtained directly from the GMS Core backend.
+  if (!prefs_->GetBoolean(
+          prefs::kUnenrolledFromGoogleMobileServicesDueToErrors) &&
+      sync_util::IsSyncFeatureEnabledIncludingPasswords(sync_service_) &&
+      bridge_helper_->CanUseGetAllLoginsWithBrandingInfoAPI()) {
+    affiliations_prefetcher_->DisablePrefetching();
+  }
 }
 
 void PasswordStoreAndroidBackend::GetAutofillableLoginsAsyncInternal(
diff --git a/chrome/browser/password_manager/android/password_store_android_backend.h b/chrome/browser/password_manager/android/password_store_android_backend.h
index 30c41de..0e6a5ba 100644
--- a/chrome/browser/password_manager/android/password_store_android_backend.h
+++ b/chrome/browser/password_manager/android/password_store_android_backend.h
@@ -30,6 +30,8 @@
 
 namespace password_manager {
 
+class AffiliationsPrefetcher;
+
 // These values are persisted to logs. Entries should not be renumbered and
 // numeric values should never be reused. Update enums.xml whenever updating
 // this enum.
@@ -92,14 +94,17 @@
     : public PasswordStoreBackend,
       public PasswordStoreAndroidBackendReceiverBridge::Consumer {
  public:
-  explicit PasswordStoreAndroidBackend(PrefService* prefs);
+  PasswordStoreAndroidBackend(
+      PrefService* prefs,
+      AffiliationsPrefetcher* affiliations_prefetcher);
   PasswordStoreAndroidBackend(
       base::PassKey<class PasswordStoreAndroidBackendTest>,
       std::unique_ptr<PasswordStoreAndroidBackendBridgeHelper> bridge_helper,
       std::unique_ptr<PasswordManagerLifecycleHelper> lifecycle_helper,
       std::unique_ptr<PasswordSyncControllerDelegateAndroid>
           sync_controller_delegate,
-      PrefService* prefs);
+      PrefService* prefs,
+      AffiliationsPrefetcher* affiliations_prefetcher);
   ~PasswordStoreAndroidBackend() override;
 
  private:
@@ -368,6 +373,8 @@
 
   raw_ptr<PrefService> prefs_ = nullptr;
 
+  raw_ptr<AffiliationsPrefetcher> affiliations_prefetcher_ = nullptr;
+
   base::Time initialized_at_ = base::Time::Now();
 
   // This will be set to false once the first foregrounding has been handled.
diff --git a/chrome/browser/password_manager/android/password_store_android_backend_unittest.cc b/chrome/browser/password_manager/android/password_store_android_backend_unittest.cc
index 317e51e8..203d0ce 100644
--- a/chrome/browser/password_manager/android/password_store_android_backend_unittest.cc
+++ b/chrome/browser/password_manager/android/password_store_android_backend_unittest.cc
@@ -24,8 +24,10 @@
 #include "chrome/browser/password_manager/android/password_store_android_backend_dispatcher_bridge.h"
 #include "chrome/browser/password_manager/android/password_store_android_backend_receiver_bridge.h"
 #include "chrome/browser/password_manager/android/password_sync_controller_delegate_android.h"
+#include "components/password_manager/core/browser/affiliation/affiliations_prefetcher.h"
 #include "components/password_manager/core/browser/affiliation/fake_affiliation_service.h"
 #include "components/password_manager/core/browser/affiliation/mock_affiliated_match_helper.h"
+#include "components/password_manager/core/browser/affiliation/mock_affiliation_service.h"
 #include "components/password_manager/core/browser/features/password_features.h"
 #include "components/password_manager/core/browser/password_form.h"
 #include "components/password_manager/core/browser/password_manager_test_utils.h"
@@ -196,6 +198,11 @@
 class PasswordStoreAndroidBackendTest : public testing::Test {
  protected:
   PasswordStoreAndroidBackendTest() {
+    mock_affiliation_service_ =
+        std::make_unique<testing::NiceMock<MockAffiliationService>>();
+    affiliations_prefetcher_ =
+        std::make_unique<AffiliationsPrefetcher>(mock_affiliation_service());
+
     prefs_.registry()->RegisterBooleanPref(
         prefs::kUnenrolledFromGoogleMobileServicesDueToErrors, false);
     prefs_.registry()->RegisterBooleanPref(
@@ -212,7 +219,8 @@
     backend_ = std::make_unique<PasswordStoreAndroidBackend>(
         base::PassKey<class PasswordStoreAndroidBackendTest>(),
         CreateMockBridgeHelper(), CreateFakeLifecycleHelper(),
-        CreatePasswordSyncControllerDelegate(), &prefs_);
+        CreatePasswordSyncControllerDelegate(), &prefs_,
+        affiliations_prefetcher_.get());
   }
 
   ~PasswordStoreAndroidBackendTest() override {
@@ -236,6 +244,9 @@
     return sync_controller_delegate_;
   }
   PrefService* prefs() { return &prefs_; }
+  MockAffiliationService* mock_affiliation_service() {
+    return mock_affiliation_service_.get();
+  }
   void RunUntilIdle() { task_environment_.RunUntilIdle(); }
 
   void EnableSyncForTestAccount() {
@@ -259,7 +270,7 @@
   std::unique_ptr<PasswordStoreAndroidBackendBridgeHelper>
   CreateMockBridgeHelper() {
     auto unique_bridge_helper = std::make_unique<
-        StrictMock<MockPasswordStoreAndroidBackendBridgeHelper>>();
+        NiceMock<MockPasswordStoreAndroidBackendBridgeHelper>>();
     bridge_helper_ = unique_bridge_helper.get();
     EXPECT_CALL(*bridge_helper_, SetConsumer);
     return unique_bridge_helper;
@@ -281,9 +292,10 @@
     return unique_delegate;
   }
 
+  std::unique_ptr<MockAffiliationService> mock_affiliation_service_;
+  std::unique_ptr<AffiliationsPrefetcher> affiliations_prefetcher_;
   std::unique_ptr<PasswordStoreAndroidBackend> backend_;
-  raw_ptr<StrictMock<MockPasswordStoreAndroidBackendBridgeHelper>>
-      bridge_helper_;
+  raw_ptr<NiceMock<MockPasswordStoreAndroidBackendBridgeHelper>> bridge_helper_;
   raw_ptr<FakePasswordManagerLifecycleHelper> lifecycle_helper_;
   raw_ptr<PasswordSyncControllerDelegateAndroid> sync_controller_delegate_;
   syncer::TestSyncService sync_service_;
@@ -1562,6 +1574,20 @@
   RunUntilIdle();
 }
 
+TEST_F(PasswordStoreAndroidBackendTest, DisablesAffiliationsPrefetching) {
+  backend().InitBackend(/*affiliated_match_helper=*/nullptr,
+                        PasswordStoreAndroidBackend::RemoteChangesReceived(),
+                        base::RepeatingClosure(), base::DoNothing());
+  EnableSyncForTestAccount();
+
+  EXPECT_CALL(*bridge_helper(), CanUseGetAllLoginsWithBrandingInfoAPI)
+      .WillOnce(Return(true));
+  // Expect call to clear cache of all affiliations.
+  EXPECT_CALL(*mock_affiliation_service(),
+              KeepPrefetchForFacets(testing::IsEmpty()));
+  backend().OnSyncServiceInitialized(sync_service());
+}
+
 class PasswordStoreAndroidBackendTestForMetrics
     : public PasswordStoreAndroidBackendTest,
       public testing::WithParamInterface<bool> {
diff --git a/chrome/browser/password_manager/multi_profile_credentials_filter_unittest.cc b/chrome/browser/password_manager/multi_profile_credentials_filter_unittest.cc
index cd15c6a..09e936d0 100644
--- a/chrome/browser/password_manager/multi_profile_credentials_filter_unittest.cc
+++ b/chrome/browser/password_manager/multi_profile_credentials_filter_unittest.cc
@@ -256,7 +256,9 @@
   AccountInfo account_info = SetupInterception();
   dice_web_signin_interceptor_->MaybeInterceptWebSignin(
       browser()->tab_strip_model()->GetActiveWebContents(),
-      account_info.account_id, /*is_new_account=*/true,
+      account_info.account_id,
+      signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN,
+      /*is_new_account=*/true,
       /*is_sync_signin=*/false);
   ASSERT_TRUE(dice_web_signin_interceptor_->is_interception_in_progress());
 
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc
index dc575bd..511f1a2 100644
--- a/chrome/browser/password_manager/password_manager_browsertest.cc
+++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -4101,9 +4101,11 @@
   base::HistogramTester histogram_tester;
   DiceWebSigninInterceptor* signin_interceptor =
       helper_.GetSigninInterceptor(profile);
-  signin_interceptor->MaybeInterceptWebSignin(WebContents(), account_id,
-                                              /*is_new_account=*/true,
-                                              /*is_sync_signin=*/false);
+  signin_interceptor->MaybeInterceptWebSignin(
+      WebContents(), account_id,
+      signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN,
+      /*is_new_account=*/true,
+      /*is_sync_signin=*/false);
   EXPECT_FALSE(signin_interceptor->is_interception_in_progress());
   histogram_tester.ExpectUniqueSample(
       "Signin.Intercept.HeuristicOutcome",
@@ -4130,9 +4132,11 @@
   base::HistogramTester histogram_tester;
   DiceWebSigninInterceptor* signin_interceptor =
       helper_.GetSigninInterceptor(profile);
-  signin_interceptor->MaybeInterceptWebSignin(WebContents(), account_id,
-                                              /*is_new_account=*/true,
-                                              /*is_sync_signin=*/false);
+  signin_interceptor->MaybeInterceptWebSignin(
+      WebContents(), account_id,
+      signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN,
+      /*is_new_account=*/true,
+      /*is_sync_signin=*/false);
   EXPECT_FALSE(signin_interceptor->is_interception_in_progress());
   histogram_tester.ExpectUniqueSample(
       "Signin.Intercept.HeuristicOutcome",
@@ -4161,9 +4165,11 @@
   base::HistogramTester histogram_tester;
   DiceWebSigninInterceptor* signin_interceptor =
       helper_.GetSigninInterceptor(profile);
-  signin_interceptor->MaybeInterceptWebSignin(WebContents(), account_id,
-                                              /*is_new_account=*/true,
-                                              /*is_sync_signin=*/false);
+  signin_interceptor->MaybeInterceptWebSignin(
+      WebContents(), account_id,
+      signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN,
+      /*is_new_account=*/true,
+      /*is_sync_signin=*/false);
   EXPECT_TRUE(signin_interceptor->is_interception_in_progress());
 }
 
@@ -4184,9 +4190,11 @@
   base::HistogramTester histogram_tester;
   DiceWebSigninInterceptor* signin_interceptor =
       helper_.GetSigninInterceptor(profile);
-  signin_interceptor->MaybeInterceptWebSignin(WebContents(), account_id,
-                                              /*is_new_account=*/true,
-                                              /*is_sync_signin=*/false);
+  signin_interceptor->MaybeInterceptWebSignin(
+      WebContents(), account_id,
+      signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN,
+      /*is_new_account=*/true,
+      /*is_sync_signin=*/false);
   EXPECT_TRUE(signin_interceptor->is_interception_in_progress());
 
   // Add the new password, password bubble not triggered.
diff --git a/chrome/browser/password_manager/password_manager_interactive_uitest.cc b/chrome/browser/password_manager/password_manager_interactive_uitest.cc
index ba3ca02f..d357fda 100644
--- a/chrome/browser/password_manager/password_manager_interactive_uitest.cc
+++ b/chrome/browser/password_manager/password_manager_interactive_uitest.cc
@@ -645,9 +645,11 @@
   base::HistogramTester histogram_tester;
   DiceWebSigninInterceptor* signin_interceptor =
       helper_.GetSigninInterceptor(profile);
-  signin_interceptor->MaybeInterceptWebSignin(WebContents(), account_id,
-                                              /*is_new_account=*/true,
-                                              /*is_sync_signin=*/false);
+  signin_interceptor->MaybeInterceptWebSignin(
+      WebContents(), account_id,
+      signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN,
+      /*is_new_account=*/true,
+      /*is_sync_signin=*/false);
   EXPECT_FALSE(signin_interceptor->is_interception_in_progress());
   histogram_tester.ExpectUniqueSample(
       "Signin.Intercept.HeuristicOutcome",
diff --git a/chrome/browser/password_manager/password_store_backend_factory.cc b/chrome/browser/password_manager/password_store_backend_factory.cc
index c5f00ef..7adffd9 100644
--- a/chrome/browser/password_manager/password_store_backend_factory.cc
+++ b/chrome/browser/password_manager/password_store_backend_factory.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/password_manager/password_store_backend_factory.h"
 
 #include "base/metrics/histogram_functions.h"
-
 #include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
 #include "chrome/browser/password_manager/password_manager_buildflags.h"
@@ -23,8 +22,10 @@
 #endif  // BUILDFLAG(IS_ANDROID)
 
 std::unique_ptr<password_manager::PasswordStoreBackend>
-CreatePasswordStoreBackend(const base::FilePath& login_db_directory,
-                           PrefService* prefs) {
+CreatePasswordStoreBackend(
+    const base::FilePath& login_db_directory,
+    PrefService* prefs,
+    password_manager::AffiliationsPrefetcher* affiliations_prefetcher) {
   TRACE_EVENT0("passwords", "PasswordStoreBackendCreation");
 #if !BUILDFLAG(IS_ANDROID) || BUILDFLAG(USE_LEGACY_PASSWORD_STORE_BACKEND)
   return std::make_unique<password_manager::PasswordStoreBuiltInBackend>(
@@ -52,7 +53,8 @@
             password_manager::CreateLoginDatabaseForProfileStorage(
                 login_db_directory),
             syncer::WipeModelUponSyncDisabledBehavior::kNever),
-        std::make_unique<password_manager::PasswordStoreAndroidBackend>(prefs),
+        std::make_unique<password_manager::PasswordStoreAndroidBackend>(
+            prefs, affiliations_prefetcher),
         prefs);
   }
   return std::make_unique<password_manager::PasswordStoreBuiltInBackend>(
diff --git a/chrome/browser/password_manager/password_store_backend_factory.h b/chrome/browser/password_manager/password_store_backend_factory.h
index 2c0886dd..3554ca8 100644
--- a/chrome/browser/password_manager/password_store_backend_factory.h
+++ b/chrome/browser/password_manager/password_store_backend_factory.h
@@ -12,11 +12,14 @@
 class PrefService;
 
 namespace password_manager {
+class AffiliationsPrefetcher;
 class PasswordStoreBackend;
 }
 
 std::unique_ptr<password_manager::PasswordStoreBackend>
-CreatePasswordStoreBackend(const base::FilePath& login_db_directory,
-                           PrefService* prefs);
+CreatePasswordStoreBackend(
+    const base::FilePath& login_db_directory,
+    PrefService* prefs,
+    password_manager::AffiliationsPrefetcher* affiliations_prefetcher);
 
 #endif  // CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_BACKEND_FACTORY_H_
diff --git a/chrome/browser/password_manager/profile_password_store_factory.cc b/chrome/browser/password_manager/profile_password_store_factory.cc
index 5f96c6db..6dbb087 100644
--- a/chrome/browser/password_manager/profile_password_store_factory.cc
+++ b/chrome/browser/password_manager/profile_password_store_factory.cc
@@ -71,8 +71,9 @@
   // mechanism, if the sync service isn't created yet, we proceed as if the
   // user isn't syncing which forces moving the passwords to the Android backend
   // to avoid data loss.
-  ps = new password_manager::PasswordStore(
-      CreatePasswordStoreBackend(profile->GetPath(), profile->GetPrefs()));
+  ps = new password_manager::PasswordStore(CreatePasswordStoreBackend(
+      profile->GetPath(), profile->GetPrefs(),
+      AffiliationsPrefetcherFactory::GetForProfile(profile)));
 #else
   NOTIMPLEMENTED();
 #endif
diff --git a/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc b/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc
index 6081a2e..a7209ef 100644
--- a/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc
+++ b/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc
@@ -147,10 +147,11 @@
     graph->PassToGraph(
         std::make_unique<
             performance_manager::policies::OomScorePolicyChromeOS>());
-    graph->PassToGraph(
-        std::make_unique<
-            performance_manager::policies::ReportPageProcessesPolicy>());
   }
+
+  graph->PassToGraph(
+      std::make_unique<
+          performance_manager::policies::ReportPageProcessesPolicy>());
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
 
 #if !BUILDFLAG(IS_ANDROID)
diff --git a/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor.cc b/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor.cc
index 9b32ce0..e6fb04f 100644
--- a/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor.cc
+++ b/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor.cc
@@ -11,12 +11,9 @@
 #include "base/check.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
-#include "base/process/process_handle.h"
-#include "base/process/process_metrics.h"
 #include "base/sequence_checker.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/time/time.h"
-#include "build/build_config.h"
 #include "components/performance_manager/public/features.h"
 #include "components/performance_manager/public/graph/frame_node.h"
 #include "components/performance_manager/public/graph/graph.h"
@@ -27,78 +24,32 @@
 #include "components/performance_manager/public/resource_attribution/attribution_helpers.h"
 #include "components/performance_manager/public/resource_attribution/query_results.h"
 #include "components/performance_manager/public/resource_attribution/resource_contexts.h"
-#include "content/public/browser/browser_child_process_host.h"
 #include "content/public/common/process_type.h"
 
 namespace performance_manager::metrics {
 
-namespace {
-
 using resource_attribution::PageContext;
 using resource_attribution::ResourceContext;
 
-class CPUMeasurementDelegateImpl final
-    : public PageTimelineCPUMonitor::CPUMeasurementDelegate {
- public:
-  // Default factory function.
-  static std::unique_ptr<CPUMeasurementDelegate> Create(
-      const ProcessNode* process_node) {
-    return std::make_unique<CPUMeasurementDelegateImpl>(process_node);
-  }
-
-  explicit CPUMeasurementDelegateImpl(const ProcessNode* process_node);
-  ~CPUMeasurementDelegateImpl() final = default;
-
-  base::TimeDelta GetCumulativeCPUUsage() final;
-
- private:
-  std::unique_ptr<base::ProcessMetrics> process_metrics_;
-};
-
-CPUMeasurementDelegateImpl::CPUMeasurementDelegateImpl(
-    const ProcessNode* process_node) {
-  const base::ProcessHandle handle = process_node->GetProcess().Handle();
-#if BUILDFLAG(IS_MAC)
-  process_metrics_ = base::ProcessMetrics::CreateProcessMetrics(
-      handle, content::BrowserChildProcessHost::GetPortProvider());
-#else
-  process_metrics_ = base::ProcessMetrics::CreateProcessMetrics(handle);
-#endif
-}
-
-base::TimeDelta CPUMeasurementDelegateImpl::GetCumulativeCPUUsage() {
-#if BUILDFLAG(IS_WIN)
-  return process_metrics_->GetPreciseCumulativeCPUUsage();
-#else
-  return process_metrics_->GetCumulativeCPUUsage();
-#endif
-}
-
-}  // namespace
-
 PageTimelineCPUMonitor::PageTimelineCPUMonitor()
     : cpu_measurement_delegate_factory_(
-          base::BindRepeating(&CPUMeasurementDelegateImpl::Create)) {}
+          CPUMeasurementDelegate::GetDefaultFactory()) {}
 
 PageTimelineCPUMonitor::~PageTimelineCPUMonitor() = default;
 
 void PageTimelineCPUMonitor::SetCPUMeasurementDelegateFactoryForTesting(
     Graph* graph,
-    CPUMeasurementDelegate::FactoryCallback factory) {
+    CPUMeasurementDelegate::Factory* factory) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (features::kUseResourceAttributionCPUMonitor.Get()) {
     CPUMeasurementDelegate::SetDelegateFactoryForTesting(  // IN_TEST
-        graph, std::move(factory));
+        graph, factory);
     return;
   }
   // Ensure that all CPU measurements use the same delegate.
   CHECK(cpu_measurement_map_.empty());
-  if (factory.is_null()) {
-    cpu_measurement_delegate_factory_ =
-        base::BindRepeating(&CPUMeasurementDelegateImpl::Create);
-  } else {
-    cpu_measurement_delegate_factory_ = std::move(factory);
-  }
+  CHECK(factory);
+  cpu_measurement_delegate_factory_ = factory;
 }
 
 void PageTimelineCPUMonitor::StartMonitoring(Graph* graph) {
@@ -118,8 +69,7 @@
   // Start monitoring CPU usage for all existing processes. Can't read their
   // CPU usage until they have a pid assigned.
   for (const ProcessNode* process_node : graph->GetAllProcessNodes()) {
-    if (process_node->GetProcessType() == content::PROCESS_TYPE_RENDERER &&
-        process_node->GetProcessId() != base::kNullProcessId) {
+    if (cpu_measurement_delegate_factory_->ShouldMeasureProcess(process_node)) {
       MonitorCPUUsage(process_node);
     }
   }
@@ -207,20 +157,13 @@
     CHECK(cpu_measurement_map_.empty());
     return;
   }
-  // Only handle process start notifications (which is when the pid is
-  // assigned), not exit notifications.
-  if (!process_node->GetProcess().IsValid()) {
-    return;
-  }
-  CHECK_NE(process_node->GetProcessId(), base::kNullProcessId);
-  if (process_node->GetProcessType() != content::PROCESS_TYPE_RENDERER) {
-    return;
-  }
-  auto it = cpu_measurement_map_.find(process_node);
-  if (it == cpu_measurement_map_.end()) {
-    // Process isn't being measured yet so it must have been created while
-    // measurements were already started.
-    MonitorCPUUsage(process_node);
+  if (cpu_measurement_delegate_factory_->ShouldMeasureProcess(process_node)) {
+    auto it = cpu_measurement_map_.find(process_node);
+    if (it == cpu_measurement_map_.end()) {
+      // Process isn't being measured yet so it must have been created while
+      // measurements were already started.
+      MonitorCPUUsage(process_node);
+    }
   }
 }
 
@@ -238,7 +181,9 @@
   CHECK_EQ(process_node->GetProcessType(), content::PROCESS_TYPE_RENDERER);
   const auto& [it, was_inserted] = cpu_measurement_map_.emplace(
       process_node,
-      CPUMeasurement(cpu_measurement_delegate_factory_.Run(process_node)));
+      CPUMeasurement(
+          cpu_measurement_delegate_factory_->CreateDelegateForProcess(
+              process_node)));
   CHECK(was_inserted);
 }
 
diff --git a/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor.h b/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor.h
index 4e506366..6f782e99 100644
--- a/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor.h
+++ b/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor.h
@@ -9,6 +9,7 @@
 #include <memory>
 
 #include "base/functional/callback_forward.h"
+#include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
 #include "base/time/time.h"
@@ -31,7 +32,7 @@
  public:
   // A shim to request CPU measurements for a process. A new
   // CPUMeasurementDelegate object will be created for each ProcessNode to be
-  // measured. Can be overridden for testing by passing a factory callback to
+  // measured. Can be overridden for testing by passing a factory to
   // SetCPUMeasurementDelegateFactoryForTesting().
   using CPUMeasurementDelegate = resource_attribution::CPUMeasurementDelegate;
 
@@ -54,11 +55,11 @@
   PageTimelineCPUMonitor(const PageTimelineCPUMonitor& other) = delete;
   PageTimelineCPUMonitor& operator=(const PageTimelineCPUMonitor&) = delete;
 
-  // The given `factory_callback` will be called to create a
-  // CPUMeasurementDelegate for each ProcessNode in `graph` to be measured.
+  // The given `factory` will be used to create a CPUMeasurementDelegate for
+  // each ProcessNode in `graph` to be measured.
   void SetCPUMeasurementDelegateFactoryForTesting(
       Graph* graph,
-      CPUMeasurementDelegate::FactoryCallback factory_callback);
+      CPUMeasurementDelegate::Factory* factory);
 
   // Starts monitoring CPU usage for all renderer ProcessNode's in `graph`.
   void StartMonitoring(Graph* graph);
@@ -143,9 +144,9 @@
   // a measurement interval).
   base::TimeTicks last_measurement_time_ GUARDED_BY_CONTEXT(sequence_checker_);
 
-  // Callback that will be invoked to create CPUMeasurementDelegate objects for
-  // each ProcessNode being measured.
-  CPUMeasurementDelegate::FactoryCallback cpu_measurement_delegate_factory_
+  // Factory that creates CPUMeasurementDelegate objects for each ProcessNode
+  // being measured.
+  raw_ptr<CPUMeasurementDelegate::Factory> cpu_measurement_delegate_factory_
       GUARDED_BY_CONTEXT(sequence_checker_);
 
   // If the kUseResourceAttributionCPUMonitor feature parameter is enabled,
diff --git a/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor_unittest.cc b/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor_unittest.cc
index 670594b..1b576ff 100644
--- a/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor_unittest.cc
+++ b/chrome/browser/performance_manager/metrics/page_timeline_cpu_monitor_unittest.cc
@@ -141,8 +141,11 @@
     mock_utility_process_->SetProcess(base::Process::Current(),
                                       /*launch_time=*/base::TimeTicks::Now());
 
-    cpu_monitor_.SetCPUMeasurementDelegateFactoryForTesting(
-        graph(), delegate_factory_.GetFactoryCallback());
+    // These tests validate specific timing of measurements around process
+    // creation and destruction.
+    delegate_factory_.SetRequireValidProcesses(true);
+    cpu_monitor_.SetCPUMeasurementDelegateFactoryForTesting(graph(),
+                                                            &delegate_factory_);
   }
 
   // Creates a renderer process containing a single page and frame, for simple
diff --git a/chrome/browser/performance_manager/metrics/page_timeline_monitor_unittest.cc b/chrome/browser/performance_manager/metrics/page_timeline_monitor_unittest.cc
index c9eb107..a631706 100644
--- a/chrome/browser/performance_manager/metrics/page_timeline_monitor_unittest.cc
+++ b/chrome/browser/performance_manager/metrics/page_timeline_monitor_unittest.cc
@@ -75,7 +75,7 @@
     monitor_->SetShouldCollectSliceCallbackForTesting(
         base::BindRepeating([]() { return true; }));
     monitor_->cpu_monitor_.SetCPUMeasurementDelegateFactoryForTesting(
-        graph(), cpu_delegate_factory_.GetFactoryCallback());
+        graph(), &cpu_delegate_factory_);
     graph()->PassToGraph(std::move(monitor));
     ResetHistogramTester();
     ResetUkmRecorder();
diff --git a/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_host.cc b/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_host.cc
index 05462b1f..3bb290d 100644
--- a/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_host.cc
+++ b/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_host.cc
@@ -39,7 +39,8 @@
 LCPCriticalPathPredictorHost::~LCPCriticalPathPredictorHost() = default;
 
 void LCPCriticalPathPredictorHost::SetLcpElementLocator(
-    const std::string& lcp_element_locator) {
+    const std::string& lcp_element_locator,
+    bool lcp_timing_was_predicted) {
   // `LcpCriticalPathPredictorPageLoadMetricsObserver::OnCommit()` stores
   // `LcpCriticalPathPredictorPageLoadMetricsObserver` in `PageData` as a weak
   // pointer. This weak pointer can be deleted at any time.
@@ -48,7 +49,7 @@
               render_frame_host().GetPage())) {
     if (auto* plmo =
             page_data->GetLcpCriticalPathPredictorPageLoadMetricsObserver()) {
-      plmo->SetLcpElementLocator(lcp_element_locator);
+      plmo->SetLcpElementLocator(lcp_element_locator, lcp_timing_was_predicted);
     }
   }
 }
diff --git a/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_host.h b/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_host.h
index 87cd90f..52afacc 100644
--- a/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_host.h
+++ b/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_host.h
@@ -39,7 +39,8 @@
   ~LCPCriticalPathPredictorHost() override;
 
   // Implements blink::mojom::LCPCriticalPathPredictorHost.
-  void SetLcpElementLocator(const std::string& lcp_element_locator) override;
+  void SetLcpElementLocator(const std::string& lcp_element_locator,
+                            bool lcp_timing_was_predicted) override;
   void SetLcpInfluencerScriptUrls(
       const std::vector<GURL>& lcp_influencer_scripts) override;
   void NotifyFetchedFont(const GURL& font_url) override;
diff --git a/chrome/browser/preloading/prefetch/search_prefetch/search_preload_unified_browsertest.cc b/chrome/browser/preloading/prefetch/search_prefetch/search_preload_unified_browsertest.cc
index 2243ff6..8e37829 100644
--- a/chrome/browser/preloading/prefetch/search_prefetch/search_preload_unified_browsertest.cc
+++ b/chrome/browser/preloading/prefetch/search_prefetch/search_preload_unified_browsertest.cc
@@ -53,6 +53,7 @@
 #include "third_party/blink/public/common/features.h"
 
 #if BUILDFLAG(IS_ANDROID)
+#include "chrome/browser/toolbar_manager_test_helper_android.h"
 #include "chrome/test/base/android/android_browser_test.h"
 #else  // BUILDFLAG(IS_ANDROID)
 #include "chrome/browser/ui/browser.h"
@@ -89,6 +90,14 @@
       : prerender_helper_(base::BindRepeating(
             &SearchPreloadUnifiedBrowserTest::GetActiveWebContents,
             base::Unretained(this))) {
+#if BUILDFLAG(IS_ANDROID)
+    // Skips recreating the Android ChromeTabbedActivity when
+    // homepage settings are changed.
+    // This happens when the feature chrome::android::kStartSurfaceAndroid is
+    // enabled (currently enabled by default).
+    toolbar_manager::setSkipRecreateForTesting(true);
+#endif  // BUILDFLAG(IS_ANDROID)
+
     scoped_feature_list_.InitWithFeaturesAndParameters(
         {
             {features::kSupportSearchSuggestionForPrerender2,
diff --git a/chrome/browser/preloading/prerender/prerender_browsertest.cc b/chrome/browser/preloading/prerender/prerender_browsertest.cc
index 3665f88f..3c24bdf 100644
--- a/chrome/browser/preloading/prerender/prerender_browsertest.cc
+++ b/chrome/browser/preloading/prerender/prerender_browsertest.cc
@@ -50,6 +50,7 @@
 constexpr int kFinalStatusActivated = 0;
 constexpr int kFinalStatusInvalidSchemeNavigation = 6;
 constexpr int kFinalStatusTriggerDestroyed = 16;
+constexpr int kFinalStatusTabClosedWithoutUserGesture = 55;
 constexpr int kFinalStatusCrossSiteNavigationInMainFrameNavigation = 64;
 
 }  // namespace
@@ -620,6 +621,44 @@
       kFinalStatusCrossSiteNavigationInMainFrameNavigation, 1);
 }
 
+IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
+                       PrerenderWebContentsDelegate_CloseContents) {
+  base::HistogramTester histogram_tester;
+
+  // Navigate to an initial page.
+  GURL url = embedded_test_server()->GetURL("/prerender/simple_links.html");
+  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));
+
+  // Start a prerender.
+  GURL prerender_url = embedded_test_server()->GetURL("/prerender/empty.html");
+  content::TestNavigationObserver nav_observer(prerender_url);
+  nav_observer.StartWatchingNewWebContents();
+  prerender_helper().AddPrerendersAsync({prerender_url},
+                                        /*eagerness=*/absl::nullopt, "_blank");
+  nav_observer.WaitForNavigationFinished();
+  EXPECT_EQ(nav_observer.last_navigation_url(), prerender_url);
+  int host_id = prerender_helper().GetHostForUrl(prerender_url);
+  EXPECT_NE(host_id, content::RenderFrameHost::kNoFrameTreeNodeId);
+
+  // Navigate a prerendered page to another page.
+  GURL navigation_url =
+      embedded_test_server()->GetURL("/prerender/empty.html?navigated");
+  prerender_helper().NavigatePrerenderedPage(host_id, navigation_url);
+
+  // WebContents::Close() should eventually call
+  // PrerenderWebContentsDelegate::CloseContents() that cancels prerendering.
+  auto* prerender_web_contents =
+      content::WebContents::FromFrameTreeNodeId(host_id);
+  ASSERT_TRUE(prerender_web_contents);
+  prerender_web_contents->Close();
+  EXPECT_EQ(prerender_helper().GetHostForUrl(prerender_url),
+            content::RenderFrameHost::kNoFrameTreeNodeId);
+
+  histogram_tester.ExpectUniqueSample(
+      "Prerender.Experimental.PrerenderHostFinalStatus.SpeculationRule",
+      kFinalStatusTabClosedWithoutUserGesture, 1);
+}
+
 class PrerenderNewTabPageBrowserTest
     : public PrerenderBrowserTest,
       public testing::WithParamInterface<content::PreloadingPredictor> {
diff --git a/chrome/browser/printing/browser_printing_context_factory_for_test.cc b/chrome/browser/printing/browser_printing_context_factory_for_test.cc
index 33291cc..10dea3c 100644
--- a/chrome/browser/printing/browser_printing_context_factory_for_test.cc
+++ b/chrome/browser/printing/browser_printing_context_factory_for_test.cc
@@ -44,6 +44,9 @@
   auto context =
       MakeDefaultTestPrintingContext(delegate, process_behavior, printer_name_);
 
+  if (failed_error_for_update_printer_settings_) {
+    context->SetUpdatePrinterSettingsFails();
+  }
   if (cancels_in_new_document_) {
     context->SetNewDocumentCancels();
   }
@@ -89,6 +92,11 @@
   printer_name_ = printer_name;
 }
 
+void BrowserPrintingContextFactoryForTest::
+    SetFailedErrorOnUpdatePrinterSettings() {
+  failed_error_for_update_printer_settings_ = true;
+}
+
 void BrowserPrintingContextFactoryForTest::SetCancelErrorOnNewDocument(
     bool cause_errors) {
   cancels_in_new_document_ = cause_errors;
diff --git a/chrome/browser/printing/browser_printing_context_factory_for_test.h b/chrome/browser/printing/browser_printing_context_factory_for_test.h
index b9a2798..65e001d3 100644
--- a/chrome/browser/printing/browser_printing_context_factory_for_test.h
+++ b/chrome/browser/printing/browser_printing_context_factory_for_test.h
@@ -27,6 +27,7 @@
       PrintingContext::ProcessBehavior process_behavior) override;
 
   void SetPrinterNameForSubsequentContexts(const std::string& printer_name);
+  void SetFailedErrorOnUpdatePrinterSettings();
   void SetCancelErrorOnNewDocument(bool cause_errors);
   void SetFailedErrorOnNewDocument(bool cause_errors);
   void SetAccessDeniedErrorOnNewDocument(bool cause_errors);
@@ -45,6 +46,7 @@
 
  private:
   std::string printer_name_;
+  bool failed_error_for_update_printer_settings_ = false;
   bool cancels_in_new_document_ = false;
   bool failed_error_for_new_document_ = false;
   bool access_denied_errors_for_new_document_ = false;
diff --git a/chrome/browser/printing/print_browsertest.cc b/chrome/browser/printing/print_browsertest.cc
index 9d91909..ca33961 100644
--- a/chrome/browser/printing/print_browsertest.cc
+++ b/chrome/browser/printing/print_browsertest.cc
@@ -485,11 +485,7 @@
   content::SetupCrossSiteRedirector(embedded_test_server());
   ASSERT_TRUE(embedded_test_server()->Start());
 
-  // `run_loop_` and `quit_callback_` are initialized here to avoid having a
-  // race between the last expected `CheckForQuit()` call and
-  // `WaitUntilCallbackReceived()` being called.
-  run_loop_ = std::make_unique<base::RunLoop>();
-  quit_callback_ = run_loop_->QuitClosure();
+  PrepareRunloop();
 }
 
 void PrintBrowserTest::TearDownOnMainThread() {
@@ -669,6 +665,14 @@
           base::Unretained(GetFrameContent(render_frame_host))));
 }
 
+void PrintBrowserTest::PrepareRunloop() {
+  // `run_loop_` and `quit_callback_` are initialized together to avoid having
+  // a race between the last expected `CheckForQuit()` call and
+  // `WaitUntilCallbackReceived()` being called.
+  run_loop_ = std::make_unique<base::RunLoop>();
+  quit_callback_ = run_loop_->QuitClosure();
+}
+
 void PrintBrowserTest::OnNewDocument(
 #if BUILDFLAG(IS_MAC)
     bool destination_is_preview,
diff --git a/chrome/browser/printing/print_browsertest.h b/chrome/browser/printing/print_browsertest.h
index d7ecc89..07a7530 100644
--- a/chrome/browser/printing/print_browsertest.h
+++ b/chrome/browser/printing/print_browsertest.h
@@ -82,6 +82,9 @@
   }
 
  protected:
+  // Initialize a run loop for a testing sequence.
+  void PrepareRunloop();
+
   void OnNewDocument(
 #if BUILDFLAG(IS_MAC)
       bool destination_is_preview,
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
index 5c39228..dbd646c 100644
--- a/chrome/browser/printing/print_view_manager_base.cc
+++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -384,7 +384,7 @@
   // dialog is cancelled.
   if (printer_query->last_status() == mojom::ResultCode::kCanceled) {
 #if BUILDFLAG(ENABLE_OOP_PRINTING)
-    if (features::ShouldPrintJobOop() && query_with_ui_client_id_.has_value()) {
+    if (features::ShouldPrintJobOop()) {
       UnregisterSystemPrintClient();
     }
 #endif
@@ -400,6 +400,11 @@
 
   if (!printer_query->cookie() || !printer_query->settings().dpi()) {
     PRINTER_LOG(ERROR) << "Unable to update print settings";
+#if BUILDFLAG(ENABLE_OOP_PRINTING)
+    if (printing::features::kEnableOopPrintDriversJobPrint.Get()) {
+      UnregisterSystemPrintClient();
+    }
+#endif
     std::move(callback).Run(base::Value("Update settings failed"));
     return;
   }
diff --git a/chrome/browser/printing/printer_query_oop.cc b/chrome/browser/printing/printer_query_oop.cc
index e56050d..9c1366a 100644
--- a/chrome/browser/printing/printer_query_oop.cc
+++ b/chrome/browser/printing/printer_query_oop.cc
@@ -251,6 +251,16 @@
     // unregister it.  Just drop any local reference to it.
     query_with_ui_client_id_.reset();
 
+    // With the failure to update the setting, the registered client must be
+    // released.  The context ID is also no longer relevant to use.
+    if (print_document_client_id_.has_value()) {
+      PrintBackendServiceManager::GetInstance().UnregisterClient(
+          print_document_client_id_.value());
+      print_document_client_id_.reset();
+      CHECK(context_id_.has_value());
+      context_id_.reset();
+    }
+
     // TODO(crbug.com/809738)  Fill in support for handling of access-denied
     // result code.
   } else {
diff --git a/chrome/browser/printing/system_access_process_print_browsertest.cc b/chrome/browser/printing/system_access_process_print_browsertest.cc
index ee085d45..31319425 100644
--- a/chrome/browser/printing/system_access_process_print_browsertest.cc
+++ b/chrome/browser/printing/system_access_process_print_browsertest.cc
@@ -46,6 +46,7 @@
 #include "chrome/browser/printing/print_backend_service_manager.h"
 #include "chrome/browser/printing/print_backend_service_test_impl.h"
 #include "chrome/browser/printing/print_job_worker_oop.h"
+#include "chrome/browser/printing/print_preview_dialog_controller.h"
 #include "chrome/browser/printing/printer_query_oop.h"
 #include "chrome/services/printing/public/mojom/print_backend_service.mojom.h"
 #endif
@@ -117,6 +118,18 @@
     base::RepeatingCallback<void(bool allowed)>;
 #endif  // BUILDFLAG(ENABLE_PRINT_CONTENT_ANALYSIS)
 
+void CancelPrintPreview(content::WebContents* preview_dialog) {
+  // This script locates and clicks the Cancel button for a Print Preview
+  // dialog.
+  const char kScript[] = R"(
+      const button = document.getElementsByTagName('print-preview-app')[0]
+                       .$['sidebar']
+                       .shadowRoot.querySelector('print-preview-button-strip')
+                       .shadowRoot.querySelector('.cancel-button');
+      button.click();)";
+  ASSERT_TRUE(content::ExecJs(preview_dialog, kScript));
+}
+
 }  // namespace
 
 #if BUILDFLAG(ENABLE_OOP_PRINTING)
@@ -154,6 +167,7 @@
     ErrorCheckCallback error_check_callback;
     OnUseDefaultSettingsCallback did_use_default_settings_callback;
     OnGetSettingsWithUICallback did_get_settings_with_ui_callback;
+    OnDidUpdatePrintSettingsCallback did_update_print_settings_callback;
   };
 
   TestPrintJobWorker(
@@ -194,6 +208,14 @@
                    TestPrintJobWorker::PrintCallbacks* callbacks)
       : PrinterQuery(rfh_id), callbacks_(callbacks) {}
 
+  void UpdatePrintSettings(base::Value::Dict new_settings,
+                           SettingsCallback callback) override {
+    PrinterQuery::UpdatePrintSettings(
+        std::move(new_settings),
+        base::BindOnce(&TestPrinterQuery::OnDidUpdatePrintSettings,
+                       base::Unretained(this), std::move(callback)));
+  }
+
   void UseDefaultSettings(SettingsCallback callback) override {
     DVLOG(1) << "Observed: invoke use default settings";
     PrinterQuery::UseDefaultSettings(std::move(callback));
@@ -210,6 +232,14 @@
     callbacks_->did_get_settings_with_ui_callback.Run();
   }
 
+  void OnDidUpdatePrintSettings(SettingsCallback callback,
+                                std::unique_ptr<PrintSettings> settings,
+                                mojom::ResultCode result) {
+    DVLOG(1) << "Observed: update print settings";
+    std::move(callback).Run(std::move(settings), result);
+    callbacks_->did_update_print_settings_callback.Run(result);
+  }
+
   std::unique_ptr<PrintJobWorker> CreatePrintJobWorker(
       PrintJob* print_job) override {
     return std::make_unique<TestPrintJobWorker>(
@@ -516,6 +546,10 @@
           base::BindRepeating(
               &SystemAccessProcessPrintBrowserTestBase::OnGetSettingsWithUI,
               base::Unretained(this));
+      test_print_job_worker_callbacks_
+          .did_update_print_settings_callback = base::BindRepeating(
+          &SystemAccessProcessPrintBrowserTestBase::OnDidUpdatePrintSettings,
+          base::Unretained(this));
     }
     test_create_printer_query_callback_ = base::BindRepeating(
         &SystemAccessProcessPrintBrowserTestBase::CreatePrinterQuery,
@@ -568,6 +602,12 @@
   }
 
   // PrintViewManagerBase::TestObserver:
+  void OnPrintPreviewDone() override {
+    if (check_for_print_preview_done_) {
+      CheckForQuit();
+    }
+  }
+
   void OnRegisterSystemPrintClient(bool succeeded) override {
     system_print_registration_succeeded_ = succeeded;
   }
@@ -623,21 +663,27 @@
     std::ignore = SetUpAndReturnPrintViewManager(web_contents);
   }
 
-  void PrintAfterPreviewIsReadyAndLoaded() {
-    PrintAfterPreviewIsReadyAndLoaded(PrintParams());
+  content::WebContents* PrintAfterPreviewIsReadyAndLoaded() {
+    return PrintAfterPreviewIsReadyAndLoaded(PrintParams());
   }
 
-  void PrintAfterPreviewIsReadyAndLoaded(const PrintParams& params) {
-    PrintAfterPreviewIsReadyAndMaybeLoaded(params, /*wait_for_loaded=*/true);
+  content::WebContents* PrintAfterPreviewIsReadyAndLoaded(
+      const PrintParams& params) {
+    return PrintAfterPreviewIsReadyAndMaybeLoaded(params,
+                                                  /*wait_for_loaded=*/true);
   }
 
-  void PrintAfterPreviewIsReadyAndMaybeLoaded(const PrintParams& params,
-                                              bool wait_for_loaded) {
+  content::WebContents* PrintAfterPreviewIsReadyAndMaybeLoaded(
+      const PrintParams& params,
+      bool wait_for_loaded) {
     // First invoke the Print Preview dialog with requested method.
     content::WebContents* preview_dialog =
         wait_for_loaded ? PrintAndWaitUntilPreviewIsReadyAndLoaded(params)
                         : PrintAndWaitUntilPreviewIsReady(params);
-    ASSERT_TRUE(preview_dialog);
+    if (!preview_dialog) {
+      ADD_FAILURE() << "Unable to get Print Preview dialog";
+      return nullptr;
+    }
 
     // Print Preview is completely ready, can now initiate printing.
     // This script locates and clicks the Print button.
@@ -662,12 +708,12 @@
     // logs should show the assert.  Otherwise the crashes for this bug should
     // change to become the test timeouts.
     if (!result) {
-      LOG(ERROR) << "ExecJs() failed; if reason is because the renderer "
-                    "terminated, it is possibly okay?";
-      LOG(ERROR) << result.message();
+      ADD_FAILURE() << "ExecJs() failed; if reason is because the renderer "
+                       "terminated, it is possibly okay? "
+                    << result.message();
     }
     WaitUntilCallbackReceived();
-    ASSERT_TRUE(result);
+    return preview_dialog;
   }
 
   void AdjustMediaAfterPreviewIsReadyAndLoaded() {
@@ -768,6 +814,10 @@
   }
 #endif
 
+  void PrimeForFailInUpdatePrinterSettings() {
+    test_printing_context_factory()->SetFailedErrorOnUpdatePrinterSettings();
+  }
+
   void PrimeForCancelInNewDocument() {
     test_printing_context_factory()->SetCancelErrorOnNewDocument(
         /*cause_errors=*/true);
@@ -808,6 +858,10 @@
         /*cause_errors=*/true);
   }
 
+  void SetCheckForPrintPreviewDone(bool check) {
+    check_for_print_preview_done_ = check;
+  }
+
   const absl::optional<bool> system_print_registration_succeeded() const {
     return system_print_registration_succeeded_;
   }
@@ -995,6 +1049,7 @@
 
   base::test::ScopedFeatureList feature_list_;
 #if BUILDFLAG(ENABLE_OOP_PRINTING)
+  bool check_for_print_preview_done_ = false;
   TestPrintJobWorker::PrintCallbacks test_print_job_worker_callbacks_;
   TestPrintJobWorkerOop::PrintCallbacks test_print_job_worker_oop_callbacks_;
   CreatePrinterQueryCallback test_create_printer_query_callback_;
@@ -1193,6 +1248,84 @@
 #endif
 }
 
+// TODO(crbug.com/1500150): Consistently failing on Linux. Re-enable.
+#if BUILDFLAG(IS_LINUX)
+#define MAYBE_UpdatePrintSettingsFails DISABLED_UpdatePrintSettingsFails
+#else
+#define MAYBE_UpdatePrintSettingsFails UpdatePrintSettingsFails
+#endif
+IN_PROC_BROWSER_TEST_P(SystemAccessProcessPrintBrowserTest,
+                       MAYBE_UpdatePrintSettingsFails) {
+  AddPrinter("printer1");
+  SetPrinterNameForSubsequentContexts("printer1");
+  PrimeForFailInUpdatePrinterSettings();
+
+  ASSERT_TRUE(embedded_test_server()->Started());
+  GURL url(embedded_test_server()->GetURL("/printing/test3.html"));
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
+
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  ASSERT_TRUE(web_contents);
+  SetUpPrintViewManager(web_contents);
+
+  // The expected events for this are:
+  // 1.  Update print settings, which fails.  No print job is created.
+  SetNumExpectedMessages(/*num=*/1);
+
+  // Since the preview is loaded before initiating the Print, the error
+  // is displayed in the preview and the dialog remains open.
+  content::WebContents* preview_dialog = PrintAfterPreviewIsReadyAndLoaded();
+  ASSERT_TRUE(preview_dialog);
+
+  EXPECT_EQ(update_print_settings_result(), mojom::ResultCode::kFailed);
+
+  // Need to close the dialog to ensure proper cleanup is done before
+  // sanity checks at test termination.  This posts to UI thread to close,
+  // so need to ensure that has a chance to run before terminating.
+  CancelPrintPreview(preview_dialog);
+  base::RunLoop().RunUntilIdle();
+}
+
+IN_PROC_BROWSER_TEST_P(SystemAccessProcessPrintBrowserTest,
+                       UpdatePrintSettingsFailsErrorDialog) {
+  AddPrinter("printer1");
+  SetPrinterNameForSubsequentContexts("printer1");
+  PrimeForFailInUpdatePrinterSettings();
+
+  ASSERT_TRUE(embedded_test_server()->Started());
+  GURL url(embedded_test_server()->GetURL("/printing/test3.html"));
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
+
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  ASSERT_TRUE(web_contents);
+  SetUpPrintViewManager(web_contents);
+
+  // The expected events for this are:
+  // 1.  Update print settings, which fails.  No print job is created.
+  // TODO(crbug.com/1495120):  Update expectations once an error dialog is
+  // shown to the user after this failure.
+  SetNumExpectedMessages(/*num=*/1);
+  PrintAfterPreviewIsReadyAndMaybeLoaded(PrintParams(),
+                                         /*wait_for_loaded=*/false);
+
+  // Print Preview dialog will have been closed, ensure that the UI thread
+  // runs all posted tasks to reflect that before checking it is gone.
+  base::RunLoop().RunUntilIdle();
+  content::WebContents* preview_dialog =
+      PrintPreviewDialogController::GetInstance()->GetPrintPreviewForContents(
+          web_contents);
+  ASSERT_FALSE(preview_dialog);
+
+  EXPECT_EQ(update_print_settings_result(), mojom::ResultCode::kFailed);
+
+  // Initiating printing before the document is ready hides the Print Preview
+  // dialog.  No error is shown to the user when this happens.
+  // TODO(crbug.com/1495120):  Update once an error message is shown.
+  EXPECT_EQ(error_dialog_shown_count(), 0u);
+}
+
 IN_PROC_BROWSER_TEST_F(SystemAccessProcessSandboxedServicePrintBrowserTest,
                        StartPrinting) {
   AddPrinter("printer1");
@@ -1366,14 +1499,12 @@
     // No error dialog is shown.
     SetNumExpectedMessages(/*num=*/4);
   } else {
-    // There are no callbacks for print stages with in-browser printing.  So
-    // the print job is started, but that fails, and there is no capturing of
-    // that result.
     // The expected events for this are:
-    // 1.  Print job is started, but is canceled and destroyed due to failure
+    // 1.  Update print settings.
+    // 2.  Print job is started, but is canceled and destroyed due to failure
     //     during PDF conversion failure.
     // No error dialog is shown.
-    SetNumExpectedMessages(/*num=*/1);
+    SetNumExpectedMessages(/*num=*/2);
   }
   PrintAfterPreviewIsReadyAndLoaded();
 
@@ -1419,13 +1550,13 @@
     //     finished cleanly before completing the test.
     SetNumExpectedMessages(/*num=*/5);
   } else {
-    // There are no callbacks for print stages with in-browser printing.  So
-    // the print job is started, but that fails and gets canceled.
+    // The print job is started, but that fails and gets canceled.
     // The expected events for this are:
-    // 1.  An error dialog is shown.
-    // 2.  Wait for the one print job to be destroyed, to ensure printing
+    // 1.  Update print settings.
+    // 2.  An error dialog is shown.
+    // 3.  Wait for the one print job to be destroyed, to ensure printing
     //     finished cleanly before completing the test.
-    SetNumExpectedMessages(/*num=*/2);
+    SetNumExpectedMessages(/*num=*/3);
   }
 
   PrintAfterPreviewIsReadyAndLoaded();
@@ -1467,9 +1598,10 @@
   } else {
     // A print job is started, but results in a cancel.  There are no callbacks
     // to notice the start job.  The expected events for this are:
-    // 1.  Wait for the one print job to be destroyed, to ensure printing
+    // 1.  Update print settings.
+    // 2.  Wait for the one print job to be destroyed, to ensure printing
     //     finished cleanly before completing the test.
-    SetNumExpectedMessages(/*num=*/1);
+    SetNumExpectedMessages(/*num=*/2);
   }
 
   PrintAfterPreviewIsReadyAndLoaded();
@@ -1777,11 +1909,14 @@
 #endif  // BUILDFLAG(IS_WIN)
   } else {
 #if BUILDFLAG(IS_WIN)
-    // There are no callbacks that trigger for print stages with in-browser
-    // printing for the Windows case.  The only expected event for this is to
-    // wait for the one print job to be destroyed, to ensure printing finished
-    // cleanly before completing the test.
-    SetNumExpectedMessages(/*num=*/1);
+    // Once the transition to system print is initiated, the expected events
+    // are:
+    // 1.  Update print settings.
+    // 2.  There are no other callbacks that trigger for print stages with
+    //     in-browser printing for the Windows case.  The only other expected
+    //     event for this is to wait for the one print job to be destroyed, to
+    //     ensure printing finished cleanly before completing the test.
+    SetNumExpectedMessages(/*num=*/2);
 #else
     // Once the transition to system print is initiated, the expected events
     // are:
@@ -1824,15 +1959,111 @@
 }
 
 #if BUILDFLAG(IS_WIN)
+// This test is Windows-only because of Print Preview behavior in
+// `onPrintWithSystemDialog_()`.  For Windows this call ends up going through
+// `PrintViewManagerBase::PrintForPrintPreview()`, and thus invokes
+// `UpdatePrintSettings()` before displaying the system dialog.  Other
+// platforms end up going through `PrintViewManager::PrintForSystemDialogNow()`
+// and thus do not update print settings before the system dialog is displayed.
+IN_PROC_BROWSER_TEST_P(SystemAccessProcessPrintBrowserTest,
+                       SystemPrintFromPrintPreviewUpdatePrintSettingsFails) {
+  AddPrinter("printer1");
+  SetPrinterNameForSubsequentContexts("printer1");
+  PrimeForFailInUpdatePrinterSettings();
+
+  ASSERT_TRUE(embedded_test_server()->Started());
+  GURL url(embedded_test_server()->GetURL("/printing/test3.html"));
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
+
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  ASSERT_TRUE(web_contents);
+  SetUpPrintViewManager(web_contents);
+
+  // Once the transition to system print is initiated, the expected events
+  // are:
+  // 1.  Update the print settings, which fails.  No further printing calls
+  //     are made.  No print job is created because of such an early failure.
+  SetNumExpectedMessages(/*num=*/1);
+
+  SystemPrintFromPreviewOnceReadyAndLoaded(/*wait_for_callback=*/true);
+
+  EXPECT_EQ(update_print_settings_result(), mojom::ResultCode::kFailed);
+  // TODO(crbug.com/1495120):  Update once an error dialog is shown for this
+  // failure to print.
+  EXPECT_EQ(error_dialog_shown_count(), 0u);
+}
+
+// This test is Windows-only because of Print Preview behavior in
+// `onPrintWithSystemDialog_()`.  For Windows this call ends up going through
+// `PrintViewManagerBase::PrintForPrintPreview()`, and thus invokes
+// `UpdatePrintSettings()` before displaying the system dialog.  Other
+// platforms end up going through `PrintViewManager::PrintForSystemDialogNow()`
+// and thus do not update print settings before the system dialog is displayed.
+IN_PROC_BROWSER_TEST_F(
+    SystemAccessProcessSandboxedServicePrintBrowserTest,
+    PrintPreviewAfterSystemPrintFromPrintPreviewUpdatePrintSettingsFails) {
+  AddPrinter("printer1");
+  SetPrinterNameForSubsequentContexts("printer1");
+  PrimeForFailInUpdatePrinterSettings();
+
+  ASSERT_TRUE(embedded_test_server()->Started());
+  GURL url(embedded_test_server()->GetURL("/printing/test3.html"));
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
+
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+  ASSERT_TRUE(web_contents);
+  SetUpPrintViewManager(web_contents);
+
+  // First invoke system print from Print Preview.  Must wait until the
+  // PrintPreviewUI is completely done before proceeding to the second part
+  // of this test to ensure that the client is unregistered from the
+  // `PrintBackendServiceManager`.
+  SetCheckForPrintPreviewDone(/*check=*/true);
+
+  // Once the transition to system print is initiated, the expected events
+  // are:
+  // 1.  Update the print settings, which fails.  No further printing calls
+  //     are made.  No print job is created because of such an early failure.
+  // 2.  Print Preview UI is done.
+  SetNumExpectedMessages(/*num=*/2);
+  SystemPrintFromPreviewOnceReadyAndLoaded(/*wait_for_callback=*/true);
+
+  EXPECT_EQ(update_print_settings_result(), mojom::ResultCode::kFailed);
+  // TODO(crbug.com/1495120):  Update once an error dialog is shown for this
+  // failure to print.
+  EXPECT_EQ(error_dialog_shown_count(), 0u);
+
+  // Reset before initiating another Print Preview.
+  PrepareRunloop();
+  ResetNumReceivedMessages();
+
+  // No longer expect the `PrintPreviewUI` to issue a done callback as part of
+  // the test expectations, since the Print Preview will stay open displaying
+  // an error message.  There will still be a preview done callback during
+  // test shutdown though, so disable doing an expectation check for that.
+  SetCheckForPrintPreviewDone(/*check=*/false);
+
+  // The expected events for this are:
+  // 1.  Update the print settings, which fails.  No further printing calls
+  //     are made.  No print job is created because of such an early failure.
+  SetNumExpectedMessages(/*num=*/1);
+  PrintAfterPreviewIsReadyAndLoaded();
+
+  EXPECT_EQ(update_print_settings_result(), mojom::ResultCode::kFailed);
+  // TODO(crbug.com/1495120):  Update once an error dialog is shown for this
+  // failure to print.
+  EXPECT_EQ(error_dialog_shown_count(), 0u);
+}
+
 // This test is Windows-only, since it is the only platform which can invoke
 // the system print dialog from within `PrintingContext::UpdatePrintSettings()`.
 // From that system dialog we can cause a cancel to occur.
 // TODO(crbug.com/809738):  Expand this to also cover in-browser, once an
 // appropriate signal is available to use for tracking expected events.
-// TODO(crbug.com/1435566):  Enable this test once it works without the need
-// for --single-process-tests flag.
 IN_PROC_BROWSER_TEST_F(SystemAccessProcessSandboxedServicePrintBrowserTest,
-                       DISABLED_SystemPrintFromPrintPreviewCancelRetry) {
+                       SystemPrintFromPrintPreviewCancelRetry) {
   AddPrinter("printer1");
   SetPrinterNameForSubsequentContexts("printer1");
   PrimeForCancelInAskUserForSettings();
@@ -1846,11 +2077,18 @@
   ASSERT_TRUE(web_contents);
   SetUpPrintViewManager(web_contents);
 
+  // First invoke system print from Print Preview.  Must wait until the
+  // PrintPreviewUI is completely done before proceeding to the second part
+  // of this test to ensure that the client is unregistered from the
+  // `PrintBackendServiceManager`.
+  SetCheckForPrintPreviewDone(/*check=*/true);
+
   // The expected events for this are:
   // 1.  Update the print settings, which indicates to cancel the print
-  //     request.  No further printing calls are made.
-  // No print job is created because of such an early cancel.
-  SetNumExpectedMessages(/*num=*/1);
+  //     request.  No further printing calls are made.  No print job is
+  //     created because of such an early cancel.
+  // 2.  Print Preview UI is done.
+  SetNumExpectedMessages(/*num=*/2);
 
   SystemPrintFromPreviewOnceReadyAndLoaded(/*wait_for_callback=*/true);
 
@@ -1860,6 +2098,7 @@
 
   // Now try to initiate the system print from a Print Preview again.
   // Same number of expected events.
+  PrepareRunloop();
   ResetNumReceivedMessages();
 
   SystemPrintFromPreviewOnceReadyAndLoaded(/*wait_for_callback=*/true);
@@ -2967,9 +3206,10 @@
       // The expected events for this are:
       // 1.  The document is composited for content analysis.
       // 2.  The print job used for scanning is destroyed.
-      // 3.  Wait for the actual printing job to be destroyed, to ensure
+      // 3.  Update print settings for actual printing job.
+      // 4.  Wait for the actual printing job to be destroyed, to ensure
       //     printing finished cleanly before completing the test.
-      SetNumExpectedMessages(/*num=*/3);
+      SetNumExpectedMessages(/*num=*/4);
     }
     PrintAfterPreviewIsReadyAndLoaded();
   } else {
@@ -3035,9 +3275,10 @@
       // The expected events for this are:
       // 1.  The document is composited for content analysis.
       // 2.  The print job used for scanning is destroyed.
-      // 3.  Wait for the actual printing job to be destroyed, to ensure
+      // 3.  Update print settings for actual printing job.
+      // 4.  Wait for the actual printing job to be destroyed, to ensure
       //     printing finished cleanly before completing the test.
-      SetNumExpectedMessages(/*num=*/3);
+      SetNumExpectedMessages(/*num=*/4);
     }
     const PrintParams kParams{.invoke_method =
                                   InvokePrintMethod::kWindowDotPrint};
@@ -3130,9 +3371,10 @@
       // The expected events for this are:
       // 1.  The document is composited for content analysis.
       // 2.  The print job used for scanning is destroyed.
-      // 3.  Wait for the actual printing job to be destroyed, to ensure
+      // 3.  Update print settings for actual printing job.
+      // 4.  Wait for the actual printing job to be destroyed, to ensure
       //     printing finished cleanly before completing the test.
-      SetNumExpectedMessages(/*num=*/3);
+      SetNumExpectedMessages(/*num=*/4);
 #else
       // TODO(http://b/285243428):  Update expectation once a second analysis
       // scan isn't done for system print from Print Preview.
@@ -3307,9 +3549,18 @@
     print_view_manager->set_on_print_preview_done_closure(base::BindOnce(
         &ContentAnalysisBeforePrintPreviewBrowserTest::CheckForQuit,
         base::Unretained(this)));
-    // Expect an extra message for the print job created after content
-    // analysis to be destroyed.
-    SetNumExpectedMessages(/*num=*/PrintAllowedOrNonBlockingPolicy() ? 2 : 1);
+    if (PrintAllowedOrNonBlockingPolicy()) {
+      // The expected events for this are:
+      // 1.  Update print settings.
+      // 2.  Print preview completes.
+      // 3.  Wait for the one print job to be destroyed, to ensure printing
+      //     finished cleanly before completing the test.
+      SetNumExpectedMessages(/*num=*/3);
+    } else {
+      // The expected events for this are:
+      // 1.  Print preview completes.  No print job is created.
+      SetNumExpectedMessages(/*num=*/1);
+    }
   }
 
   PrintAfterPreviewIsReadyAndLoaded();
@@ -3363,9 +3614,18 @@
     print_view_manager->set_on_print_preview_done_closure(base::BindOnce(
         &ContentAnalysisBeforePrintPreviewBrowserTest::CheckForQuit,
         base::Unretained(this)));
-    // Expect an extra message for the print job created after content
-    // analysis to be destroyed.
-    SetNumExpectedMessages(/*num=*/PrintAllowedOrNonBlockingPolicy() ? 2 : 1);
+    if (PrintAllowedOrNonBlockingPolicy()) {
+      // The expected events for this are:
+      // 1.  Update print settings.
+      // 2.  Print preview completes.
+      // 3.  Wait for the one print job to be destroyed, to ensure printing
+      //     finished cleanly before completing the test.
+      SetNumExpectedMessages(/*num=*/3);
+    } else {
+      // The expected events for this are:
+      // 1.  Print preview completes.  No print job is created.
+      SetNumExpectedMessages(/*num=*/1);
+    }
   }
 
   PrintAfterPreviewIsReadyAndMaybeLoaded(PrintParams(),
@@ -3434,9 +3694,10 @@
     } else {
 #if BUILDFLAG(IS_WIN)
       // The expected event for this is:
-      // 1.  Wait for the actual printing job to be destroyed, to ensure
+      // 1.  Update print settings.
+      // 2.  Wait for the actual printing job to be destroyed, to ensure
       //     printing finished cleanly before completing the test.
-      SetNumExpectedMessages(/*num=*/1);
+      SetNumExpectedMessages(/*num=*/2);
 #else
       // The expected events for this are:
       // 1.  Get the default settings.
@@ -3450,18 +3711,11 @@
     SystemPrintFromPreviewOnceReadyAndLoaded(/*wait_for_callback=*/true);
   } else {
 #if BUILDFLAG(IS_WIN)
-    if (UseService()) {
-      // The expected events for this are:
-      // 1.  Update print settings.
-      // 2.  The print job is cancelled.
-      // 3.  The print job is destroyed.
-      SetNumExpectedMessages(/*num=*/3);
-    } else {
-      // The expected events for this are:
-      // 1.  The print job is cancelled.
-      // 2.  The print job is destroyed.
-      SetNumExpectedMessages(/*num=*/2);
-    }
+    // The expected events for this are:
+    // 1.  Update print settings.
+    // 2.  The print job is cancelled.
+    // 3.  The print job is destroyed.
+    SetNumExpectedMessages(/*num=*/3);
 #else
     // The expected events for this are:
     // 1.  Use default settings.
@@ -3492,7 +3746,8 @@
 
 #if BUILDFLAG(IS_MAC)
 IN_PROC_BROWSER_TEST_P(ContentAnalysisAfterPrintPreviewBrowserTest,
-                       OpenPdfInPreviewFromPrintPreview) {
+                       // TODO(crbug.com/1500113): Re-enable this test
+                       DISABLED_OpenPdfInPreviewFromPrintPreview) {
   AddPrinter("printer_name");
 
   if (UseService() && !PrintAllowedOrNonBlockingPolicy()) {
diff --git a/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.cc b/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.cc
index e3428ae..5e47007 100644
--- a/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.cc
+++ b/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.cc
@@ -63,9 +63,6 @@
 // The default interval after which to adjust OOM scores.
 constexpr base::TimeDelta kAdjustmentInterval = base::Seconds(10);
 
-// The minimum interval between ReportProcesses.
-constexpr base::TimeDelta kPidsReportMinimalInterval = base::Seconds(3);
-
 // When switching to a new tab the tab's renderer's OOM score needs to be
 // updated to reflect its front-most status and protect it from discard.
 // However, doing this immediately might slow down tab switch time, so wait
@@ -282,8 +279,6 @@
   base::ProcessHandle pid =
       contents->GetPrimaryMainFrame()->GetProcess()->GetProcess().Handle();
   AdjustFocusedTabScore(pid);
-
-  ListProcessesThrottled();
 }
 
 void TabManagerDelegate::OnWindowActivated(
@@ -414,7 +409,6 @@
 
 void TabManagerDelegate::OnRenderProcessHostCreated(
     content::RenderProcessHost* host) {
-  ListProcessesThrottled();
   if (!host_observation_.IsObservingSource(host)) {
     host_observation_.AddObservation(host);
   }
@@ -448,7 +442,6 @@
                 .ptr()
                 ->GetProcess();
         AdjustFocusedTabScore(render_host->GetProcess().Handle());
-        ListProcessesThrottled();
       }
       // Do not handle the "else" case when it changes to invisible because
       // 1. The behavior is a bit awkward in that when switching from tab A to
@@ -842,76 +835,4 @@
   }
 }
 
-void TabManagerDelegate::ListProcessesThrottled() {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  ++tab_event_sequence_;
-  base::TimeTicks now = base::TimeTicks::Now();
-  if (now - last_pids_report_ > kPidsReportMinimalInterval) {
-    ListProcesses();
-  } else if (!delayed_report_timer_.IsRunning()) {
-    // If the delay timer is already scheduled, don't have to reschedule it.
-    base::TimeTicks next_report_time =
-        last_pids_report_ + kPidsReportMinimalInterval;
-    delayed_report_timer_.Start(FROM_HERE, /*delay=*/next_report_time - now,
-                                this,
-                                &TabManagerDelegate::ListProcessesDelayed);
-  }
-}
-
-void TabManagerDelegate::ListProcessesDelayed() {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  if (tab_report_sequence_ != tab_event_sequence_) {
-    ListProcesses();
-  }
-}
-
-void TabManagerDelegate::ListProcesses() {
-  if (g_browser_process->IsShuttingDown()) {
-    return;
-  }
-
-  last_pids_report_ = base::TimeTicks::Now();
-  tab_report_sequence_ = tab_event_sequence_;
-
-  std::vector<ash::ResourcedClient::Process> processes;
-  for (LifecycleUnit* lifecycle_unit : GetLifecycleUnits()) {
-    base::ProcessHandle pid = lifecycle_unit->GetProcessHandle();
-    // lifecycle_units contains entries for already-discarded tabs. If the pid
-    // is zero, we don't need to report it.
-    if (pid == base::kNullProcessHandle) {
-      continue;
-    }
-
-    DecisionDetails decision_details;
-    bool is_protected = false;
-    bool is_visible = false;
-    bool is_focused = false;
-    if (!lifecycle_unit->CanDiscard(
-            ::mojom::LifecycleUnitDiscardReason::EXTERNAL, &decision_details)) {
-      if (!decision_details.reasons().empty() &&
-          decision_details.FailureReason() ==
-              DecisionFailureReason::LIVE_STATE_VISIBLE) {
-        is_visible = true;
-
-        if (lifecycle_unit->GetLastFocusedTime() == base::TimeTicks::Max()) {
-          is_focused = true;
-        }
-      }
-      is_protected = true;
-    }
-    processes.emplace_back(pid, is_protected, is_visible, is_focused);
-  }
-
-  ReportProcesses(processes);
-}
-
-void TabManagerDelegate::ReportProcesses(
-    const std::vector<ash::ResourcedClient::Process>& processes) {
-  ash::ResourcedClient* client = ash::ResourcedClient::Get();
-  if (client) {
-    client->ReportBrowserProcesses(ash::ResourcedClient::Component::kAsh,
-                                   processes);
-  }
-}
-
 }  // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.h b/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.h
index e6383c5a..d5124ba2 100644
--- a/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.h
+++ b/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos.h
@@ -28,7 +28,6 @@
 #include "chrome/browser/resource_coordinator/tab_manager.h"
 #include "chrome/browser/ui/browser_list_observer.h"
 #include "chromeos/ash/components/dbus/debug_daemon/debug_daemon_client.h"
-#include "chromeos/ash/components/dbus/resourced/resourced_client.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
 #include "content/public/browser/render_process_host_creation_observer.h"
@@ -116,10 +115,6 @@
   // Get debugd client instance. Virtual for unit testing.
   virtual ash::DebugDaemonClient* GetDebugDaemonClient();
 
-  // Report process list of tab mainframes. Virtual for unit testing.
-  virtual void ReportProcesses(
-      const std::vector<ash::ResourcedClient::Process>& processes);
-
  private:
   FRIEND_TEST_ALL_PREFIXES(TabManagerDelegateTest, CandidatesSorted);
   FRIEND_TEST_ALL_PREFIXES(TabManagerDelegateTest,
@@ -132,7 +127,6 @@
   FRIEND_TEST_ALL_PREFIXES(TabManagerDelegateTest, KillMultipleProcesses);
   FRIEND_TEST_ALL_PREFIXES(TabManagerDelegateTest, SetOomScoreAdj);
   FRIEND_TEST_ALL_PREFIXES(TabManagerDelegateTest, TestDiscardedTabsAreSkipped);
-  FRIEND_TEST_ALL_PREFIXES(TabManagerDelegateTest, ReportProcesses);
 
   using OptionalArcProcessList = arc::ArcProcessService::OptionalArcProcessList;
 
@@ -229,15 +223,6 @@
     return base::Seconds(60);
   }
 
-  // The listing is throttled to avoid too frequent reporting.
-  void ListProcessesThrottled();
-
-  // Called by |delayed_report_timer_|.
-  void ListProcessesDelayed();
-
-  // List the tab processes for reporting.
-  void ListProcesses();
-
   // The OOM adjustment score for persistent ARC processes.
   static const int kPersistentArcAppOomScore;
 
@@ -270,17 +255,6 @@
   // Util for getting system memory status.
   std::unique_ptr<TabManagerDelegate::MemoryStat> mem_stat_;
 
-  // For throttling the renderer process list reporting.
-  base::TimeTicks last_pids_report_ = base::TimeTicks::Now();
-
-  // Delay the reporting if it's less than the minimum interval since last
-  // reporting.
-  base::OneShotTimer delayed_report_timer_;
-
-  // Sequences to check if the last tab event is handled.
-  uint64_t tab_event_sequence_ = 0;
-  uint64_t tab_report_sequence_ = 0;
-
   // Weak pointer factory used for posting tasks to other threads.
   base::WeakPtrFactory<TabManagerDelegate> weak_ptr_factory_{this};
 };
diff --git a/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos_unittest.cc b/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos_unittest.cc
index 9ffab27..b0e2481 100644
--- a/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos_unittest.cc
+++ b/chrome/browser/resource_coordinator/tab_manager_delegate_chromeos_unittest.cc
@@ -144,10 +144,6 @@
     return TabManagerDelegate::IsRecentlyKilledArcProcess(process_name, now);
   }
 
-  std::vector<ash::ResourcedClient::Process> GetReportedProcesses() {
-    return processes_;
-  }
-
  protected:
   bool KillArcProcess(const int nspid) override {
     killed_arc_processes_.push_back(nspid);
@@ -166,18 +162,12 @@
     return &debugd_client_;
   }
 
-  void ReportProcesses(
-      const std::vector<ash::ResourcedClient::Process>& processes) override {
-    processes_ = processes;
-  }
-
  private:
   LifecycleUnitVector lifecycle_units_;
   ash::FakeDebugDaemonClient debugd_client_;
   std::vector<int> killed_arc_processes_;
   LifecycleUnitVector killed_tabs_;
   bool always_return_true_from_is_recently_killed_;
-  std::vector<ash::ResourcedClient::Process> processes_;
 };
 
 class MockMemoryStat : public TabManagerDelegate::MemoryStat {
@@ -467,53 +457,4 @@
   ASSERT_EQ(&tab1, killed_tabs[0]);
 }
 
-TEST_F(TabManagerDelegateTest, ReportProcesses) {
-  MockTabManagerDelegate tab_manager_delegate;
-
-  // Tab list:
-  // tab1    pid: 11
-  // tab2    pid: 12
-  // tab3    pid: 13
-  // tab4    pid: 14
-  // tab5    pid: 15, protected
-  // tab6    pid: 16, protected, focused
-  TestLifecycleUnit tab1(base::TimeTicks(), 11);
-  tab_manager_delegate.AddLifecycleUnit(&tab1);
-  TestLifecycleUnit tab2(base::TimeTicks(), 12);
-  tab_manager_delegate.AddLifecycleUnit(&tab2);
-  TestLifecycleUnit tab3(base::TimeTicks(), 13);
-  tab_manager_delegate.AddLifecycleUnit(&tab3);
-  TestLifecycleUnit tab4(base::TimeTicks(), 14);
-  tab_manager_delegate.AddLifecycleUnit(&tab4);
-  TestLifecycleUnit tab5(base::TimeTicks(), 15, false);
-  tab_manager_delegate.AddLifecycleUnit(&tab5);
-  TestLifecycleUnit tab6(base::TimeTicks(), 16, false);
-  tab6.SetDiscardFailureReason(DecisionFailureReason::LIVE_STATE_VISIBLE);
-  tab6.SetLastFocusedTime(base::TimeTicks::Max());
-  tab_manager_delegate.AddLifecycleUnit(&tab6);
-
-  tab_manager_delegate.ListProcesses();
-
-  auto processes = tab_manager_delegate.GetReportedProcesses();
-  EXPECT_EQ(processes[0].pid, 11);
-  EXPECT_EQ(processes[0].is_protected, false);
-  EXPECT_EQ(processes[0].is_visible, false);
-  EXPECT_EQ(processes[1].pid, 12);
-  EXPECT_EQ(processes[1].is_protected, false);
-  EXPECT_EQ(processes[1].is_visible, false);
-  EXPECT_EQ(processes[2].pid, 13);
-  EXPECT_EQ(processes[2].is_protected, false);
-  EXPECT_EQ(processes[2].is_visible, false);
-  EXPECT_EQ(processes[3].pid, 14);
-  EXPECT_EQ(processes[3].is_protected, false);
-  EXPECT_EQ(processes[3].is_visible, false);
-  EXPECT_EQ(processes[4].pid, 15);
-  EXPECT_EQ(processes[4].is_protected, true);
-  EXPECT_EQ(processes[4].is_visible, false);
-  EXPECT_EQ(processes[5].pid, 16);
-  EXPECT_EQ(processes[5].is_protected, true);
-  EXPECT_EQ(processes[5].is_visible, true);
-  EXPECT_EQ(processes[5].is_focused, true);
-}
-
 }  // namespace resource_coordinator
diff --git a/chrome/browser/resources/ash/settings/os_files_page/google_drive_subpage.ts b/chrome/browser/resources/ash/settings/os_files_page/google_drive_subpage.ts
index 5e67c1a8..f701ff1 100644
--- a/chrome/browser/resources/ash/settings/os_files_page/google_drive_subpage.ts
+++ b/chrome/browser/resources/ash/settings/os_files_page/google_drive_subpage.ts
@@ -37,7 +37,7 @@
 /**
  * The preference containing the value whether bulk pinning is enabled or not.
  */
-const GOOGLE_DRIVE_BULK_PINNING_PREF = 'drivefs.bulk_pinning_enabled';
+const GOOGLE_DRIVE_BULK_PINNING_ENABLED_PREF = 'drivefs.bulk_pinning_enabled';
 
 /**
  * A list of possible confirmation dialogs that may be shown.
@@ -237,11 +237,10 @@
   }
 
   /**
-   * Returns the current bulk pinning stage, or 'unknown' if not defined.
-   * Used for testing.
+   * Returns the current bulk pinning stage, or `undefined` if not defined.
    */
-  get stage(): Stage|'unknown' {
-    return this.bulkPinningStatus_?.stage || 'unknown';
+  get stage(): Stage|undefined {
+    return this.bulkPinningStatus_?.stage;
   }
 
   override connectedCallback(): void {
@@ -271,7 +270,7 @@
   private onProgress_(status: Status): void {
     this.bulkPinningServiceUnavailable_ = false;
 
-    if (status.stage !== this.bulkPinningStatus_?.stage ||
+    if (status.stage !== this.stage ||
         status.freeSpace !== this.bulkPinningStatus_?.freeSpace ||
         status.requiredSpace !== this.bulkPinningStatus_?.requiredSpace ||
         status.listedFiles !== this.bulkPinningStatus_?.listedFiles) {
@@ -292,13 +291,13 @@
 
     let requiredSpace: number;
     try {
-      requiredSpace = parseInt(status?.requiredSpace);
+      requiredSpace = parseInt(status.requiredSpace);
     } catch (e) {
       console.error('Could not parse required space', e);
       return;
     }
 
-    this.showSpinner = (status?.stage === Stage.kSyncing && requiredSpace > 0);
+    this.showSpinner = (status.stage === Stage.kSyncing && requiredSpace > 0);
   }
 
   /**
@@ -411,7 +410,7 @@
           'googleDriveCleanUpStorageDisabledUnknownStorageTooltip');
     }
 
-    if (this.getPref(GOOGLE_DRIVE_BULK_PINNING_PREF).value &&
+    if (this.getPref(GOOGLE_DRIVE_BULK_PINNING_ENABLED_PREF).value &&
         this.contentCacheSize_ !== '0 B') {
       return this.i18n('googleDriveCleanUpStorageDisabledFileSyncTooltip');
     }
@@ -447,10 +446,10 @@
     switch (closedDialogType) {
       case ConfirmationDialogType.DISCONNECT:
         this.setPrefValue(GOOGLE_DRIVE_DISABLED_PREF, true);
-        this.setPrefValue(GOOGLE_DRIVE_BULK_PINNING_PREF, false);
+        this.setPrefValue(GOOGLE_DRIVE_BULK_PINNING_ENABLED_PREF, false);
         break;
       case ConfirmationDialogType.BULK_PINNING_DISABLE:
-        this.setPrefValue(GOOGLE_DRIVE_BULK_PINNING_PREF, false);
+        this.setPrefValue(GOOGLE_DRIVE_BULK_PINNING_ENABLED_PREF, false);
         break;
       case ConfirmationDialogType.BULK_PINNING_CLEAN_UP_STORAGE:
         await this.proxy_.handler.clearPinnedFiles();
@@ -469,8 +468,7 @@
    * sublabel.
    */
   private getBulkPinningSubLabel_(): string {
-    if (!this.bulkPinningStatus_ ||
-        this.bulkPinningStatus_?.stage !== Stage.kSuccess ||
+    if (!this.bulkPinningStatus_ || this.stage !== Stage.kSuccess ||
         this.bulkPinningServiceUnavailable_) {
       return this.i18n('googleDriveFileSyncSubtitleWithoutStorage');
     }
@@ -500,7 +498,7 @@
   private onToggleBulkPinning_(e: Event): void {
     const target = e.target as SettingsToggleButtonElement;
     const newValueAfterToggle =
-        !this.getPref(GOOGLE_DRIVE_BULK_PINNING_PREF).value;
+        !this.getPref(GOOGLE_DRIVE_BULK_PINNING_ENABLED_PREF).value;
 
     if (newValueAfterToggle) {
       this.tryEnableBulkPinning_(target);
@@ -524,14 +522,14 @@
     target.checked = false;
 
     // When the device is offline, don't allow the user to enable the toggle.
-    if (this.bulkPinningStatus_?.stage === Stage.kPausedOffline) {
+    if (this.stage === Stage.kPausedOffline) {
       this.dialogType_ = ConfirmationDialogType.BULK_PINNING_OFFLINE;
       return;
     }
 
     // If currently enumerating the files, don't allow the user to enable file
     // sync until we're certain the corpus will fit on the device.
-    if (this.bulkPinningStatus_?.stage === Stage.kListingFiles) {
+    if (this.stage === Stage.kListingFiles) {
       this.dialogType_ = ConfirmationDialogType.BULK_PINNING_LISTING_FILES;
       return;
     }
@@ -539,7 +537,7 @@
     if (this.bulkPinningStatus_?.isError) {
       // If there is not enough free space for the user to reliably turn on bulk
       // pinning, spawn a dialog.
-      if (this.bulkPinningStatus_?.stage === Stage.kNotEnoughSpace) {
+      if (this.stage === Stage.kNotEnoughSpace) {
         this.dialogType_ = ConfirmationDialogType.BULK_PINNING_NOT_ENOUGH_SPACE;
         return;
       }
@@ -551,18 +549,23 @@
     }
 
     target.checked = true;
-    this.setPrefValue(GOOGLE_DRIVE_BULK_PINNING_PREF, true);
+    this.setPrefValue(GOOGLE_DRIVE_BULK_PINNING_ENABLED_PREF, true);
     this.proxy_.handler.recordBulkPinningEnabledMetric();
   }
 
   /**
-   * Returns true if the bulk pinning preference is disabled.
+   * Returns true if the "Clean up storage" button should be enabled.
    */
-  private shouldEnableCleanUpStorageButton_(): boolean {
-    return !this.getPref(GOOGLE_DRIVE_BULK_PINNING_PREF).value &&
-        this.contentCacheSize_ !== ContentCacheSizeType.UNKNOWN &&
-        this.contentCacheSize_ !== ContentCacheSizeType.CALCULATING &&
-        this.contentCacheSize_ !== '0 B';
+  private shouldEnableCleanUpStorageButton_(
+      status: Status|null, cacheSize: string|ContentCacheSizeType): boolean {
+    const stage = status?.stage;
+    return (stage === undefined || stage === Stage.kStopped ||
+            stage === Stage.kSuccess || stage === Stage.kNotEnoughSpace ||
+            stage === Stage.kCannotGetFreeSpace ||
+            stage === Stage.kCannotListFiles ||
+            stage === Stage.kCannotEnableDocsOffline) &&
+        cacheSize !== ContentCacheSizeType.UNKNOWN &&
+        cacheSize !== ContentCacheSizeType.CALCULATING && cacheSize !== '0 B';
   }
 
   /**
diff --git a/chrome/browser/resources/ash/settings/os_settings_menu/menu_item.html b/chrome/browser/resources/ash/settings/os_settings_menu/menu_item.html
index e24e1da..5298e09 100644
--- a/chrome/browser/resources/ash/settings/os_settings_menu/menu_item.html
+++ b/chrome/browser/resources/ash/settings/os_settings_menu/menu_item.html
@@ -12,6 +12,7 @@
     color: var(--cros-text-color-primary);
     display: flex;
     flex-direction: row;
+    font: var(--cros-button-1-font);
     text-decoration: none;
   }
 
@@ -34,61 +35,6 @@
     padding-inline-end: calc(12px - var(--settings-menu-item-border-width));
   }
 
-  /* Font */
-  :host-context(body:not(.jelly-enabled)):host {
-    font-weight: 500;
-  }
-
-  :host-context(body.jelly-enabled):host {
-    font: var(--cros-button-1-font);
-  }
-
-  /* Hover state */
-  :host-context(body:not(.jelly-enabled)):host(:not(.iron-selected):hover) {
-    background-color: var(--cros-ripple-color) !important;
-  }
-
-  :host-context(body.jelly-enabled):host(:not(.iron-selected):hover) {
-    background-color: var(--cros-sys-hover_on_subtle) !important;
-  }
-
-  /* Focused state */
-  :host-context(.focus-outline-visible):host(:focus) {
-    border-color: var(--cros-focus-ring-color);
-  }
-
-  /* Selected state */
-  :host-context(body:not(.jelly-enabled)):host(.iron-selected) {
-    background-color: var(--cros-highlight-color) !important;
-    color: var(--cros-text-color-selection);
-  }
-
-  :host-context(body.jelly-enabled):host(.iron-selected) {
-    background-color: var(--cros-sys-primary) !important;
-    color: var(--cros-sys-on_primary);
-  }
-
-  /* Icon styles */
-  iron-icon {
-    pointer-events: none;
-  }
-
-  :host-context(body:not(.revamp-wayfinding-enabled)) iron-icon {
-    margin-inline-end: 16px;
-  }
-
-  :host-context(body.revamp-wayfinding-enabled) iron-icon {
-    margin-inline-end: 12px;
-  }
-
-  :host-context(body:not(.jelly-enabled)):host(.iron-selected) > iron-icon {
-    fill: var(--cros-icon-color-selection);
-  }
-
-  :host-context(body.jelly-enabled):host(.iron-selected) > iron-icon {
-    fill: var(--cros-sys-on_primary);
-  }
-
   /* Label & sublabel styles */
   #labelWrapper {
     /* Expand to fill remaining space */
@@ -109,6 +55,39 @@
     font: var(--cros-body-2-font);
   }
 
+  /* Default icon styles */
+  iron-icon {
+    pointer-events: none;
+  }
+
+  :host-context(body:not(.revamp-wayfinding-enabled)) iron-icon {
+    margin-inline-end: 16px;
+  }
+
+  :host-context(body.revamp-wayfinding-enabled) iron-icon {
+    margin-inline-end: 12px;
+  }
+
+  /* Hover state */
+  :host(:not(.iron-selected):hover) {
+    background-color: var(--cros-sys-hover_on_subtle) !important;
+  }
+
+  /* Focused state */
+  :host-context(.focus-outline-visible):host(:focus) {
+    border-color: var(--cros-focus-ring-color);
+  }
+
+  /* Selected state */
+  :host(.iron-selected) {
+    background-color: var(--cros-sys-primary) !important;
+    color: var(--cros-sys-on_primary);
+  }
+
+  :host(.iron-selected) > iron-icon {
+    fill: var(--cros-sys-on_primary);
+  }
+
   :host(.iron-selected) #sublabel {
     color: var(--cros-sys-surface_variant);
   }
diff --git a/chrome/browser/resources/ash/settings/os_settings_menu/os_settings_menu.html b/chrome/browser/resources/ash/settings/os_settings_menu/os_settings_menu.html
index 07c8c175..a269701 100644
--- a/chrome/browser/resources/ash/settings/os_settings_menu/os_settings_menu.html
+++ b/chrome/browser/resources/ash/settings/os_settings_menu/os_settings_menu.html
@@ -30,6 +30,7 @@
     box-shadow: none;
     color: var(--cros-text-color-primary);
     display: flex;
+    font: var(--cros-button-1-font);
     height: unset;
     margin-inline-end: 2px;
     margin-top: 8px;
@@ -38,14 +39,6 @@
     text-transform: none;
   }
 
-  :host-context(body:not(.jelly-enabled)) #advancedButton {
-    font-weight: 500;
-  }
-
-  :host-context(body.jelly-enabled) #advancedButton {
-    font: var(--cros-button-1-font);
-  }
-
   #advancedButton:focus {
     outline: none;
   }
diff --git a/chrome/browser/resources/ash/settings/os_settings_page/os_settings_subpage.html b/chrome/browser/resources/ash/settings/os_settings_page/os_settings_subpage.html
index fa6334c..13abb2d 100644
--- a/chrome/browser/resources/ash/settings/os_settings_page/os_settings_subpage.html
+++ b/chrome/browser/resources/ash/settings/os_settings_page/os_settings_subpage.html
@@ -14,12 +14,8 @@
   }
 
   :host(:not(.multi-card)) {
-    background-color: var(--cr-card-background-color);
-    box-shadow: var(--cr-card-shadow);
-  }
-
-  :host-context(body.jelly-enabled):host {
     background-color: var(--cros-sys-app_base);
+    box-shadow: var(--cr-card-shadow);
   }
 
   #headerLine {
@@ -39,7 +35,7 @@
     width: var(--cr-icon-ripple-size);
   }
 
-  :host-context(body.jelly-enabled) #title {
+  #title {
     font: var(--cros-button-1-font);
   }
 
diff --git a/chrome/browser/resources/ash/settings/os_settings_page/settings_card.html b/chrome/browser/resources/ash/settings/os_settings_page/settings_card.html
index 49ed507cb..86755e25 100644
--- a/chrome/browser/resources/ash/settings/os_settings_page/settings_card.html
+++ b/chrome/browser/resources/ash/settings/os_settings_page/settings_card.html
@@ -40,16 +40,12 @@
   }
 
   #card {
-    background-color: var(--cr-card-background-color);
+    background-color: var(--cros-sys-app_base);
     border-radius: var(--settings-card-border-radius);
     flex: 1;
     overflow: hidden;
   }
 
-  :host-context(body.jelly-enabled) #card {
-    background-color: var(--cros-sys-app_base);
-  }
-
   :host-context(body:not(.revamp-wayfinding-enabled)) #card {
     box-shadow: var(--cr-card-shadow);
   }
diff --git a/chrome/browser/resources/chromeos/login/debug/debug.js b/chrome/browser/resources/chromeos/login/debug/debug.js
index e862e36..04561a7 100644
--- a/chrome/browser/resources/chromeos/login/debug/debug.js
+++ b/chrome/browser/resources/chromeos/login/debug/debug.js
@@ -1767,7 +1767,7 @@
       id: 'quick-start',
       kind: ScreenKind.NORMAL,
       handledSteps:
-          'verification,connecting_to_wifi,connected_to_wifi,gaia_credentials,fido_assertion_received',
+        'verification,connecting_to_wifi,gaia_credentials,fido_assertion_received',
       states: [
         {
           id: 'PinVerification',
@@ -1789,12 +1789,6 @@
           },
         },
         {
-          id: 'ConnectedToWifi',
-          trigger: (screen) => {
-            screen.showConnectedToWifi('TestNetwork', 'TestPassword');
-          },
-        },
-        {
           id: 'TransferringGaiaCreds',
           trigger: (screen) => {
             screen.showTransferringGaiaCredentials();
diff --git a/chrome/browser/resources/chromeos/login/screens/oobe/quick_start.js b/chrome/browser/resources/chromeos/login/screens/oobe/quick_start.js
index a40809c..146d4b6 100644
--- a/chrome/browser/resources/chromeos/login/screens/oobe/quick_start.js
+++ b/chrome/browser/resources/chromeos/login/screens/oobe/quick_start.js
@@ -66,14 +66,6 @@
         value: {CIRCLE: 0, DIAMOND: 1, TRIANGLE: 2, SQUARE: 3},
         readOnly: true,
       },
-      ssid_: {
-        type: String,
-        value: '',
-      },
-      password_: {
-        type: String,
-        value: '',
-      },
       discoverableName_: {
         type: String,
         value: '',
@@ -97,8 +89,6 @@
   constructor() {
     super();
     this.UI_STEPS = QuickStartUIState;
-    this.password_ = '';
-    this.ssid_ = '';
     this.discoverableName_ = '';
     this.usePinInsteadOfQrForVerification_ = false;
     this.qrCodeCanvas = null;
@@ -109,7 +99,6 @@
       'setQRCode',
       'setPin',
       'showConnectingToWifi',
-      'showConnectedToWifi',
       'setDiscoverableName',
       'showTransferringGaiaCredentials',
       'showFidoAssertionReceived',
@@ -142,16 +131,6 @@
   }
 
   /**
-   * @param {string} ssid
-   * @param {string?} password
-   */
-  showConnectedToWifi(ssid, password) {
-    this.setUIStep(QuickStartUIState.CONNECTED_TO_WIFI);
-    this.ssid_ = ssid;
-    this.password_ = password ? password : '';
-  }
-
-  /**
    * @param {!Array<boolean>} qrCode
    */
   setQRCode(qrCode) {
@@ -186,10 +165,6 @@
     return this.shadowRoot.querySelector('#qrCodeCanvas');
   }
 
-  onWifiConnectedNextClicked_() {
-    this.userActed('wifi_connected');
-  }
-
   onCancelClicked_() {
     this.userActed('cancel');
   }
diff --git a/chrome/browser/resources/chromeos/smb_shares/smb_credentials_dialog.html b/chrome/browser/resources/chromeos/smb_shares/smb_credentials_dialog.html
index add65ab..0a07754 100644
--- a/chrome/browser/resources/chromeos/smb_shares/smb_credentials_dialog.html
+++ b/chrome/browser/resources/chromeos/smb_shares/smb_credentials_dialog.html
@@ -1,29 +1,12 @@
 <style>
   cr-dialog::part(dialog) {
+    background-color: var(--cros-sys-dialog_container);
     border-radius: 0;
     height: 100%;
     width: 100%;
   }
 
-  :host-context([theme='legacy']) cr-dialog::part(dialog) {
-    background-color: var(--cros-bg-color-elevation-3);
-  }
-
-  :host-context([theme='refresh23']) cr-dialog::part(dialog) {
-    background-color: var(--cros-sys-dialog_container);
-  }
-
-  :host-context([theme='legacy']) cr-input {
-    --cr-form-field-label-color: var(--cros-textfield-label-color);
-    --cr-input-background-color: var(--cros-textfield-background-color);
-    --cr-input-color: var(--cros-textfield-input-color);
-    --cr-input-error-color: var(--cros-textfield-label-color-error);
-    --cr-input-error-display: none;
-    --cr-input-focus-color: var(--cros-textfield-label-color-focus);
-    margin-bottom: var(--cr-form-field-bottom-spacing);
-  }
-
-  :host-context([theme='refresh23']) cr-input {
+  cr-input {
     --cr-form-field-label-color: var(--cros-sys-on_surface);
     --cr-input-background-color: var(--cros-sys-input_field_on_base);
     --cr-input-border-radius: 8px;
@@ -39,34 +22,7 @@
     margin-bottom: var(--cr-form-field-bottom-spacing);
   }
 
-  :host-context([theme='legacy']) cr-button {
-    --active-bg: transparent;
-    --active-shadow:
-        0 1px 2px var(--cros-button-active-shadow-color-key-secondary),
-        0 1px 3px var(--cros-button-active-shadow-color-ambient-secondary);
-    --active-shadow-action:
-        0 1px 2px var(--cros-button-active-shadow-color-key-primary),
-        0 1px 3px var(--cros-button-active-shadow-color-ambient-primary);
-    --bg-action: var(--cros-button-background-color-primary);
-    --border-color: var(--cros-button-stroke-color-secondary);
-    --disabled-bg-action:
-        var(--cros-button-background-color-primary-disabled);
-    --disabled-bg: var(--cros-button-background-color-primary-disabled);
-    --disabled-border-color:
-        var(--cros-button-stroke-color-secondary-disabled);
-    --disabled-text-color: var(--cros-button-label-color-secondary-disabled);
-    --hover-bg-action:
-        var(--cros-button-background-color-primary-hover-preblended);
-    --hover-bg-color: var(--cros-button-background-color-secondary-hover);
-    --hover-border-color: var(--cros-button-stroke-color-secondary-hover);
-    --ink-color: var(--cros-button-ripple-color-secondary);
-    --ripple-opacity-action: var(--cros-button-primary-ripple-opacity);
-    --ripple-opacity: var(--cros-button-secondary-ripple-opacity);
-    --text-color-action: var(--cros-button-label-color-primary);
-    --text-color: var(--cros-button-label-color-secondary);
-  }
-
-  :host-context([theme='refresh23']) cr-button {
+  cr-button {
     --active-bg: transparent;
     --active-shadow: none;
     --active-shadow-action: none;
@@ -91,36 +47,21 @@
     position: relative;
   }
 
-  :host-context([theme='refresh23']) cr-button.cancel-button {
+  cr-button.cancel-button {
     background-color: var(--cros-sys-primary_container);
   }
 
-  :host-context([theme='refresh23'])
-      cr-button.cancel-button:hover::part(hoverBackground) {
+  cr-button.cancel-button:hover::part(hoverBackground) {
     background-color: var(--cros-sys-hover_on_subtle);
     display: block;
   }
 
-  :host-context([theme='refresh23'])
-      cr-button.action-button:hover::part(hoverBackground) {
+  cr-button.action-button:hover::part(hoverBackground) {
     background-color: var(--cros-sys-hover_on_prominent);
     display: block;
   }
 
-  :host-context([theme='legacy']) cr-button.action-button {
-    --ink-color: var(--cros-button-ripple-color-primary);
-  }
-
-  :host-context([theme='legacy']):host-context(.focus-outline-visible)
-      cr-button:focus {
-    /* disable the focus shadow because we use outline below */
-    box-shadow: none;
-    outline: 2px solid var(--cros-focus-ring-color);
-    outline-offset: 2px;
-  }
-
-  :host-context([theme='refresh23']):host-context(.focus-outline-visible)
-      cr-button:focus {
+  :host-context(.focus-outline-visible) cr-button:focus {
     /* disable the focus shadow because we use outline below */
     box-shadow: none;
     outline: 2px solid var(--cros-sys-focus_ring);
@@ -131,12 +72,7 @@
     box-shadow: none;
   }
 
-  :host-context([theme='legacy']) [slot='title'] {
-    --cr-primary-text-color: var(--cros-text-color-primary);
-    padding-top: 4px;
-  }
-
-  :host-context([theme='refresh23']) [slot='title'] {
+  [slot='title'] {
     --cr-dialog-title-slot-padding-bottom: 32px;
     --cr-dialog-title-slot-padding-end: 32px;
     --cr-dialog-title-slot-padding-start: 32px;
@@ -149,17 +85,12 @@
     margin-bottom: 0;
   }
 
-  :host-context([theme='refresh23']) [slot='body'] {
+  [slot='body'] {
     --cr-dialog-body-padding-horizontal: 32px;
     --cr-form-field-bottom-spacing: 8px;
   }
 
-  :host-context([theme='legacy']) [slot='button-container']  {
-    padding-bottom: 20px;
-    padding-top: 32px;
-  }
-
-  :host-context([theme='refresh23']) [slot='button-container'] {
+  [slot='button-container'] {
     --cr-dialog-button-container-padding-bottom: 28px;
     --cr-dialog-button-container-padding-horizontal: 32px;
     padding-top: 32px;
diff --git a/chrome/browser/resources/chromeos/smb_shares/smb_credentials_dialog.js b/chrome/browser/resources/chromeos/smb_shares/smb_credentials_dialog.js
index 14b4716d..a1e654f 100644
--- a/chrome/browser/resources/chromeos/smb_shares/smb_credentials_dialog.js
+++ b/chrome/browser/resources/chromeos/smb_shares/smb_credentials_dialog.js
@@ -47,10 +47,6 @@
   created() {
     this.browserProxy_ = SmbBrowserProxyImpl.getInstance();
 
-    const jellyEnabled = loadTimeData.getBoolean('isJellyEnabled');
-    const theme = jellyEnabled ? 'refresh23' : 'legacy';
-    document.documentElement.setAttribute('theme', theme);
-
     /** @suppress {checkTypes} */
     (function() {
       ColorChangeUpdater.forDocument().start();
diff --git a/chrome/browser/resources/chromeos/smb_shares/smb_credentials_dialog_container.html b/chrome/browser/resources/chromeos/smb_shares/smb_credentials_dialog_container.html
index 53ad52d..053672d 100644
--- a/chrome/browser/resources/chromeos/smb_shares/smb_credentials_dialog_container.html
+++ b/chrome/browser/resources/chromeos/smb_shares/smb_credentials_dialog_container.html
@@ -10,11 +10,7 @@
 <link rel="stylesheet" href="chrome://theme/colors.css?sets=legacy,sys">
 <link rel="stylesheet" href="chrome://theme/typography.css">
 <style>
-  html[theme='legacy'] body {
-    background-color: var(--cros-bg-color-elevation-3);
-  }
-
-  html[theme='refresh23'] body {
+  body {
     background-color: var(--cros-sys-dialog_container);
   }
 </style>
diff --git a/chrome/browser/resources/chromeos/smb_shares/smb_share_dialog.html b/chrome/browser/resources/chromeos/smb_shares/smb_share_dialog.html
index 92b28f9b..952cef7 100644
--- a/chrome/browser/resources/chromeos/smb_shares/smb_share_dialog.html
+++ b/chrome/browser/resources/chromeos/smb_shares/smb_share_dialog.html
@@ -9,17 +9,9 @@
     width: 100%;
   }
 
-  :host-context([theme='legacy']) add-smb-share-dialog::part(title) {
-    padding-top: 4px;
-  }
-
   /* SMB dialog inside Files app is rendered inside a native dialog with fixed
     height, so we need to hard-code the body height. */
-  :host-context([theme='legacy']) add-smb-share-dialog::part(body) {
-    height: 390px;
-  }
-
-  :host-context([theme='refresh23']) add-smb-share-dialog::part(body) {
+  add-smb-share-dialog::part(body) {
     height: 425px;
   }
 </style>
diff --git a/chrome/browser/resources/chromeos/smb_shares/smb_share_dialog_container.html b/chrome/browser/resources/chromeos/smb_shares/smb_share_dialog_container.html
index 61b875f4..7b77fc7 100644
--- a/chrome/browser/resources/chromeos/smb_shares/smb_share_dialog_container.html
+++ b/chrome/browser/resources/chromeos/smb_shares/smb_share_dialog_container.html
@@ -10,11 +10,7 @@
 <link rel="stylesheet" href="chrome://theme/colors.css?sets=legacy,sys">
 <link rel="stylesheet" href="chrome://theme/typography.css">
 <style>
-  html[theme='legacy'] body {
-    background-color: var(--cros-bg-color-elevation-3);
-  }
-
-  html[theme='refresh23'] body {
+  body {
     background-color: var(--cros-sys-dialog_container);
   }
 </style>
diff --git a/chrome/browser/resources/dlp_internals/BUILD.gn b/chrome/browser/resources/dlp_internals/BUILD.gn
index f30d81c..e7f4501 100644
--- a/chrome/browser/resources/dlp_internals/BUILD.gn
+++ b/chrome/browser/resources/dlp_internals/BUILD.gn
@@ -12,6 +12,7 @@
     "app.ts",
     "dlp_clipboard_tab.ts",
     "dlp_tabs.ts",
+    "dlp_reporting_tab.ts",
   ]
   mojo_files = [ "$root_gen_dir/chrome/browser/ui/webui/dlp_internals/dlp_internals.mojom-webui.ts" ]
   mojo_files_deps =
diff --git a/chrome/browser/resources/dlp_internals/dlp_reporting_tab.html b/chrome/browser/resources/dlp_internals/dlp_reporting_tab.html
new file mode 100644
index 0000000..65dfff8
--- /dev/null
+++ b/chrome/browser/resources/dlp_internals/dlp_reporting_tab.html
@@ -0,0 +1,14 @@
+<style>
+    .bold {
+      font-weight: bold;
+    }
+
+    .red {
+      color: rgb(162, 56, 32);
+    }
+
+    div~div {
+      margin-top: 5px;
+    }
+  </style>
+  <h2>Reporting Events</h2>
diff --git a/chrome/browser/resources/dlp_internals/dlp_reporting_tab.ts b/chrome/browser/resources/dlp_internals/dlp_reporting_tab.ts
new file mode 100644
index 0000000..7e3aaf1
--- /dev/null
+++ b/chrome/browser/resources/dlp_internals/dlp_reporting_tab.ts
@@ -0,0 +1,38 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {CustomElement} from 'chrome://resources/js/custom_element.js';
+
+import {DlpEvent, PageHandler, PageHandlerInterface, ReportingObserverReceiver} from './dlp_internals.mojom-webui.js';
+import {getTemplate} from './dlp_reporting_tab.html.js';
+
+export class DlpReportingElement extends CustomElement {
+  static get is() {
+    return 'dlp-reporting-tab';
+  }
+
+  static override get template() {
+    return getTemplate();
+  }
+
+  private pageHandler_: PageHandlerInterface;
+  private readonly reportingObserver_: ReportingObserverReceiver;
+
+  constructor() {
+    super();
+
+    this.pageHandler_ = PageHandler.getRemote();
+    this.reportingObserver_ = new ReportingObserverReceiver(this);
+    this.pageHandler_.observeReporting(
+        this.reportingObserver_.$.bindNewPipeAndPassRemote());
+  }
+
+  /** Implements ReportingObserverInterface */
+  onReportEvent(event: DlpEvent): void {
+    // TODO(ayaelattar): Show it in the html page.
+    console.warn(JSON.stringify(event));
+  }
+}
+
+customElements.define(DlpReportingElement.is, DlpReportingElement);
diff --git a/chrome/browser/resources/dlp_internals/dlp_tabs.ts b/chrome/browser/resources/dlp_internals/dlp_tabs.ts
index 34f35266..facd753a 100644
--- a/chrome/browser/resources/dlp_internals/dlp_tabs.ts
+++ b/chrome/browser/resources/dlp_internals/dlp_tabs.ts
@@ -8,6 +8,7 @@
 import {CustomElement} from 'chrome://resources/js/custom_element.js';
 
 import {DlpClipboardElement} from './dlp_clipboard_tab.js';
+import {DlpReportingElement} from './dlp_reporting_tab.js';
 import {getTemplate} from './dlp_tabs.html.js';
 
 interface DlpTab {
@@ -21,10 +22,16 @@
 
 // Set of all DLP tabs. Adding a new entry here will make it automatically
 // show in the UI.
-const DLP_TABS: DlpTab[] = [{
-  title: 'Clipboard',
-  directive: DlpClipboardElement.is,
-}];
+const DLP_TABS: DlpTab[] = [
+  {
+    title: 'Clipboard',
+    directive: DlpClipboardElement.is,
+  },
+  {
+    title: 'Reporting',
+    directive: DlpReportingElement.is,
+  },
+];
 
 class DlpTabsElement extends CustomElement {
   static get is() {
diff --git a/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search/wallpaper_search.ts b/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search/wallpaper_search.ts
index 582481fd..3f813f7 100644
--- a/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search/wallpaper_search.ts
+++ b/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search/wallpaper_search.ts
@@ -27,6 +27,7 @@
 import {CustomizeChromePageCallbackRouter, CustomizeChromePageHandlerInterface, Theme} from '../customize_chrome.mojom-webui.js';
 import {CustomizeChromeApiProxy} from '../customize_chrome_api_proxy.js';
 import {DescriptorA, DescriptorDValue, Descriptors, WallpaperSearchHandlerInterface, WallpaperSearchResult, WallpaperSearchStatus} from '../wallpaper_search.mojom-webui.js';
+import {WindowProxy} from '../window_proxy.js';
 
 import {CustomizeChromeCombobox} from './combobox/customize_chrome_combobox.js';
 import {getTemplate} from './wallpaper_search.html.js';
@@ -113,7 +114,7 @@
   private descriptors_: Descriptors|null;
   private descriptorD_: string[];
   private emptyContainers_: number[];
-  private errorCallback_: (() => Promise<void>)|undefined;
+  private errorCallback_: (() => void)|undefined;
   private errorState_: ErrorState|null = null;
   private loading_: boolean;
   private results_: WallpaperSearchResult[];
@@ -187,6 +188,12 @@
           description: this.i18n('requestThrottledDescription'),
           callToAction: this.i18n('ok'),
         };
+      case WallpaperSearchStatus.kOffline:
+        return {
+          title: this.i18n('offlineTitle'),
+          description: this.i18n('offlineDescription'),
+          callToAction: this.i18n('ok'),
+        };
     }
   }
 
@@ -290,6 +297,17 @@
   }
 
   private async onSearchClick_() {
+    if (!WindowProxy.getInstance().onLine) {
+      this.errorCallback_ = () => {
+        if (WindowProxy.getInstance().onLine) {
+          this.status_ = WallpaperSearchStatus.kOk;
+          this.errorCallback_ = undefined;
+        }
+      };
+      this.status_ = WallpaperSearchStatus.kOffline;
+      return;
+    }
+
     assert(this.descriptors_);
     this.selectedDescriptorA_ = this.selectedDescriptorA_ ||
         getRandomDescriptorA(this.descriptors_.descriptorA);
diff --git a/chrome/browser/resources/side_panel/customize_chrome/window_proxy.ts b/chrome/browser/resources/side_panel/customize_chrome/window_proxy.ts
index f575cbe..714da8d 100644
--- a/chrome/browser/resources/side_panel/customize_chrome/window_proxy.ts
+++ b/chrome/browser/resources/side_panel/customize_chrome/window_proxy.ts
@@ -25,4 +25,8 @@
   now(): number {
     return Date.now();
   }
+
+  get onLine(): boolean {
+    return window.navigator.onLine;
+  }
 }
diff --git a/chrome/browser/screen_ai/screen_ai_downloader_chromeos.cc b/chrome/browser/screen_ai/screen_ai_downloader_chromeos.cc
index d9d3266..4fa5db7 100644
--- a/chrome/browser/screen_ai/screen_ai_downloader_chromeos.cc
+++ b/chrome/browser/screen_ai/screen_ai_downloader_chromeos.cc
@@ -97,7 +97,7 @@
 void ScreenAIDownloaderChromeOS::MaybeGetComponentFolderFromAsh(
     bool download_if_needed) {
   chromeos::LacrosService* impl = chromeos::LacrosService::Get();
-  if (!impl->IsAvailable<crosapi::mojom::ScreenAIDownloader>()) {
+  if (!impl || !impl->IsAvailable<crosapi::mojom::ScreenAIDownloader>()) {
     VLOG(0) << "ScreenAIDownloaderChromeOS is not available.";
     ScreenAIInstallState::GetInstance()->SetState(
         ScreenAIInstallState::State::kFailed);
@@ -134,7 +134,7 @@
 
 void ScreenAIDownloaderChromeOS::MaybeSetLastUsageTimeInAsh() {
   chromeos::LacrosService* impl = chromeos::LacrosService::Get();
-  if (!impl->IsAvailable<crosapi::mojom::ScreenAIDownloader>()) {
+  if (!impl || !impl->IsAvailable<crosapi::mojom::ScreenAIDownloader>()) {
     VLOG(0) << "ScreenAIDownloaderChromeOS is not available.";
     return;
   }
diff --git a/chrome/browser/segmentation_platform/ukm_database_client.h b/chrome/browser/segmentation_platform/ukm_database_client.h
index 41103da..89cc4d8b 100644
--- a/chrome/browser/segmentation_platform/ukm_database_client.h
+++ b/chrome/browser/segmentation_platform/ukm_database_client.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 
+#include "base/check.h"
 #include "base/files/file_path.h"
 #include "base/memory/raw_ptr.h"
 #include "base/no_destructor.h"
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetControllerUnitTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetControllerUnitTest.java
index 0c9097e..c65f865 100644
--- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetControllerUnitTest.java
+++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/android_share_sheet/AndroidShareSheetControllerUnitTest.java
@@ -31,8 +31,8 @@
 import android.text.TextUtils;
 
 import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
 import androidx.annotation.StringRes;
-import androidx.core.os.BuildCompat;
 import androidx.lifecycle.Lifecycle.State;
 import androidx.test.ext.junit.rules.ActivityScenarioRule;
 
@@ -108,10 +108,6 @@
 @DisableFeatures({ChromeFeatureList.WEBNOTES_STYLIZE})
 @Config(shadows = {ShadowShareImageFileUtils.class, ShadowPostTask.class})
 public class AndroidShareSheetControllerUnitTest {
-    private static final String INTENT_EXTRA_CHOOSER_CUSTOM_ACTIONS =
-            "android.intent.extra.CHOOSER_CUSTOM_ACTIONS";
-    private static final String INTENT_EXTRA_CHOOSER_MODIFY_SHARE_ACTION =
-            "android.intent.extra.CHOOSER_MODIFY_SHARE_ACTION";
     private static final String KEY_CHOOSER_ACTION_ICON = "icon";
     private static final String KEY_CHOOSER_ACTION_NAME = "name";
     private static final String KEY_CHOOSER_ACTION_ACTION = "action";
@@ -210,7 +206,10 @@
 
     /** Test whether custom actions are attached to the intent. */
     @Test
-    @Config(shadows = {ShadowBuildCompatForU.class, ShadowChooserActionHelper.class})
+    @RequiresApi(api = 34)
+    @Config(
+            sdk = 34,
+            shadows = {ShadowChooserActionHelper.class})
     public void shareWithCustomAction() {
         ShareParams params =
                 new ShareParams.Builder(mWindow, "", JUnitTestGURLs.EXAMPLE_URL.getSpec())
@@ -224,7 +223,7 @@
         Intent intent = Shadows.shadowOf((Activity) mActivity).peekNextStartedActivity();
         Assert.assertNotNull(
                 "Custom action is empty.",
-                intent.getParcelableArrayExtra(INTENT_EXTRA_CHOOSER_CUSTOM_ACTIONS));
+                intent.getParcelableArrayExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS));
 
         assertCustomActions(
                 intent,
@@ -235,6 +234,8 @@
     }
 
     @Test
+    @RequiresApi(api = 34)
+    @Config(sdk = 34)
     public void shareWithoutCustomAction() {
         ShareParams params =
                 new ShareParams.Builder(mWindow, "", "")
@@ -246,11 +247,13 @@
         Intent intent = Shadows.shadowOf((Activity) mActivity).peekNextStartedActivity();
         Assert.assertNull(
                 "Custom action should be empty for 3p only share sheet.",
-                intent.getParcelableArrayExtra(INTENT_EXTRA_CHOOSER_CUSTOM_ACTIONS));
+                intent.getParcelableArrayExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS));
     }
 
     @Test
-    @Config(shadows = {ShadowBuildCompatForU.class, ShadowChooserActionHelper.class})
+    @Config(
+            sdk = 34,
+            shadows = {ShadowChooserActionHelper.class})
     public void choosePrintAction() throws CanceledException {
         CallbackHelper callbackHelper = new CallbackHelper();
         TargetChosenCallback callback =
@@ -340,7 +343,9 @@
     }
 
     @Test
-    @Config(shadows = {ShadowChooserActionHelper.class, ShadowBuildCompatForU.class})
+    @Config(
+            sdk = 34,
+            shadows = {ShadowChooserActionHelper.class})
     public void shareImageWithCustomActions() {
         Uri testImageUri = Uri.parse("content://test.image.uri");
         ShareParams params =
@@ -366,7 +371,9 @@
     }
 
     @Test
-    @Config(shadows = {ShadowChooserActionHelper.class, ShadowBuildCompatForU.class})
+    @Config(
+            sdk = 34,
+            shadows = {ShadowChooserActionHelper.class})
     public void shareImageLinkThenCopyImageAndLink() throws CanceledException {
         Uri testImageUri = Uri.parse("content://test.image.uri");
         ShareParams params =
@@ -469,11 +476,8 @@
 
     @Test
     @Config(
-            shadows = {
-                ShadowLinkToTextCoordinator.class,
-                ShadowBuildCompatForU.class,
-                ShadowChooserActionHelper.class
-            })
+            sdk = 34,
+            shadows = {ShadowLinkToTextCoordinator.class, ShadowChooserActionHelper.class})
     public void shareLinkToHighlightText() throws CanceledException {
         ShareParams params =
                 new ShareParams.Builder(mWindow, "", JUnitTestGURLs.EXAMPLE_URL.getSpec())
@@ -519,12 +523,10 @@
     }
 
     @Test
+    @RequiresApi(34)
     @Config(
-            shadows = {
-                ShadowLinkToTextCoordinator.class,
-                ShadowBuildCompatForU.class,
-                ShadowChooserActionHelper.class
-            })
+            sdk = 34,
+            shadows = {ShadowLinkToTextCoordinator.class, ShadowChooserActionHelper.class})
     public void shareLinkToHighlightTextFailed() {
         ShadowLinkToTextCoordinator.setForceToFail(true);
 
@@ -557,17 +559,14 @@
                 shareIntent.getStringExtra(Intent.EXTRA_TEXT));
         Assert.assertNull(
                 "Modify action should be null when generating link to text failed.",
-                chooserIntent.getParcelableExtra(INTENT_EXTRA_CHOOSER_MODIFY_SHARE_ACTION));
+                chooserIntent.getParcelableExtra(Intent.EXTRA_CHOOSER_MODIFY_SHARE_ACTION));
         assertCustomActions(chooserIntent);
     }
 
     @Test
     @Config(
-            shadows = {
-                ShadowBuildCompatForU.class,
-                ShadowChooserActionHelper.class,
-                ShadowQrCodeDialog.class
-            })
+            sdk = 34,
+            shadows = {ShadowChooserActionHelper.class, ShadowQrCodeDialog.class})
     public void shareQrCodeForImage() throws CanceledException {
         Uri testImageUri = Uri.parse("content://test.image.uri");
         ShareParams params =
@@ -601,7 +600,9 @@
 
     @Test
     @DisableFeatures(ChromeFeatureList.SHARE_SHEET_CUSTOM_ACTIONS_POLISH)
-    @Config(shadows = {ShadowBuildCompatForU.class, ShadowChooserActionHelper.class})
+    @Config(
+            sdk = 34,
+            shadows = {ShadowChooserActionHelper.class})
     public void ensureNonPolishActionInOrder() {
         Uri testImageUri = Uri.parse("content://test.image.uri");
         ShareParams params =
@@ -629,7 +630,9 @@
     }
 
     @Test
-    @Config(shadows = {ShadowBuildCompatForU.class, ShadowChooserActionHelper.class})
+    @Config(
+            sdk = 34,
+            shadows = {ShadowChooserActionHelper.class})
     public void webShareImageLink() throws CanceledException {
         Uri testImageUri = Uri.parse("content://test.image.uri/image.png");
         ShareParams params =
@@ -665,7 +668,9 @@
     }
 
     @Test
-    @Config(shadows = {ShadowBuildCompatForU.class, ShadowChooserActionHelper.class})
+    @Config(
+            sdk = 34,
+            shadows = {ShadowChooserActionHelper.class})
     public void webShareImageOnly() {
         Uri testImageUri = Uri.parse("content://test.image.uri");
         ShareParams params =
@@ -690,11 +695,8 @@
 
     @Test
     @Config(
-            shadows = {
-                ShadowBuildCompatForU.class,
-                ShadowChooserActionHelper.class,
-                ShadowLongScreenshotsCoordinator.class
-            })
+            sdk = 34,
+            shadows = {ShadowChooserActionHelper.class, ShadowLongScreenshotsCoordinator.class})
     public void chooseLongScreenShot() throws CanceledException {
         ShadowLongScreenshotsCoordinator.sMockInstance =
                 Mockito.mock(LongScreenshotsCoordinator.class);
@@ -724,7 +726,9 @@
     }
 
     @Test
-    @Config(shadows = {ShadowBuildCompatForU.class, ShadowChooserActionHelper.class})
+    @Config(
+            sdk = 34,
+            shadows = {ShadowChooserActionHelper.class})
     public void shareScreenshot() {
         Uri testImageUri = Uri.parse("content://test.screenshot.uri");
         // Build the same params and share extras as sharing a long screenshot
@@ -758,7 +762,7 @@
 
     private void runModifyActionFromChooserIntent(Intent chooserIntent) throws CanceledException {
         Bundle modifyAction =
-                chooserIntent.getParcelableExtra(INTENT_EXTRA_CHOOSER_MODIFY_SHARE_ACTION);
+                chooserIntent.getParcelableExtra(Intent.EXTRA_CHOOSER_MODIFY_SHARE_ACTION);
         PendingIntent action = modifyAction.getParcelable(KEY_CHOOSER_ACTION_ACTION);
         action.send();
         ShadowLooper.idleMainLooper();
@@ -766,7 +770,7 @@
 
     private void assertCustomActions(Intent chooserIntent, Integer... expectedStringRes) {
         Parcelable[] actions =
-                chooserIntent.getParcelableArrayExtra(INTENT_EXTRA_CHOOSER_CUSTOM_ACTIONS);
+                chooserIntent.getParcelableArrayExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS);
         if (expectedStringRes.length == 0) {
             Assert.assertTrue(
                     "No custom actions are expected.", actions == null || actions.length == 0);
@@ -794,7 +798,7 @@
     private void chooseCustomAction(Intent chooserIntent, @StringRes int iconLabel)
             throws CanceledException {
         Parcelable[] actions =
-                chooserIntent.getParcelableArrayExtra(INTENT_EXTRA_CHOOSER_CUSTOM_ACTIONS);
+                chooserIntent.getParcelableArrayExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS);
         Assert.assertTrue("More than one action is provided.", actions.length > 0);
 
         // Find the print callback, since we mocked that out during this test.
@@ -834,16 +838,6 @@
         }
     }
 
-    // Work around shadow to assume runtime is at least U.
-    // TODO(https://crbug.com/1420388): Switch to @Config(sdk=34) this once API 34 exists.
-    @Implements(BuildCompat.class)
-    public static class ShadowBuildCompatForU {
-        @Implementation
-        protected static boolean isAtLeastU() {
-            return true;
-        }
-    }
-
     // Shadow class to bypass actually saving the image as URL for this test.
     @Implements(ShareImageFileUtils.class)
     static class ShadowShareImageFileUtils {
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.cc b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.cc
index 6500284..ee7e6b7 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.cc
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.cc
@@ -20,7 +20,17 @@
 
 namespace {
 using Result = BoundSessionRefreshCookieFetcher::Result;
+
+void RecordNumberOfSuccessiveTimeoutIfAny(size_t successive_timeout) {
+  if (successive_timeout == 0) {
+    return;
+  }
+
+  base::UmaHistogramCounts100(
+      "Signin.BoundSessionCredentials.ThrottledRequestsSuccessiveTimeout",
+      successive_timeout);
 }
+}  // namespace
 
 BoundSessionCookieControllerImpl::BoundSessionCookieControllerImpl(
     unexportable_keys::UnexportableKeyService& key_service,
@@ -48,6 +58,7 @@
   // On shutdown or session termination, resume blocked requests if any.
   ResumeBlockedRequests(
       ResumeBlockedRequestsTrigger::kShutdownOrSessionTermination);
+  RecordNumberOfSuccessiveTimeoutIfAny(successive_timeout_);
 }
 
 void BoundSessionCookieControllerImpl::Initialize() {
@@ -127,6 +138,8 @@
   it->second = expiration_time;
   if (AreAllCookiesFresh()) {
     ResumeBlockedRequests(ResumeBlockedRequestsTrigger::kObservedFreshCookies);
+    RecordNumberOfSuccessiveTimeoutIfAny(successive_timeout_);
+    successive_timeout_ = 0;
   }
 
   if (min_cookie_expiration_time() != old_min_expiration_time) {
@@ -186,7 +199,6 @@
 
 void BoundSessionCookieControllerImpl::OnCookieRefreshFetched(
     BoundSessionRefreshCookieFetcher::Result result) {
-  // TODO(b/263263352): Record histogram with the result of the fetch.
   refresh_cookie_fetcher_.reset();
 
   ResumeBlockedRequestsTrigger trigger =
@@ -194,6 +206,8 @@
           ? ResumeBlockedRequestsTrigger::kCookieRefreshFetchSuccess
           : ResumeBlockedRequestsTrigger::kCookieRefreshFetchFailure;
   // Resume blocked requests regardless of the result.
+  // `SetCookieExpirationTimeAndNotify()` should be called around the same time
+  // as `OnCookieRefreshFetched()` if the fetch was successful.
   ResumeBlockedRequests(trigger);
 
   // Persistent errors result in session termination.
@@ -243,4 +257,5 @@
   // kResumeBlockedRequestTimeout. New requests will trigger a new fetch.
   refresh_cookie_fetcher_.reset();
   ResumeBlockedRequests(ResumeBlockedRequestsTrigger::kTimeout);
+  successive_timeout_++;
 }
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.h b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.h
index 67663c0..bf23351 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.h
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl.h
@@ -126,6 +126,7 @@
   base::OneShotTimer preemptive_cookie_refresh_timer_;
   // Used to release blocked requests after a timeout.
   base::OneShotTimer resume_blocked_requests_timer_;
+  size_t successive_timeout_ = 0;
 
   RefreshCookieFetcherFactoryForTesting
       refresh_cookie_fetcher_factory_for_testing_;
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl_unittest.cc b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl_unittest.cc
index 1e82d980..981d8b43 100644
--- a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl_unittest.cc
+++ b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_controller_impl_unittest.cc
@@ -8,6 +8,7 @@
 
 #include "base/containers/span.h"
 #include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/task_environment.h"
 #include "base/test/test_future.h"
@@ -674,6 +675,57 @@
           base::Bucket(BoundSessionCookieControllerImpl::
                            ResumeBlockedRequestsTrigger::kTimeout,
                        /*count=*/1)));
+
+  ResetBoundSessionCookieController();
+  histogram_tester()->ExpectUniqueSample(
+      "Signin.BoundSessionCredentials.ThrottledRequestsSuccessiveTimeout", 1,
+      1);
+}
+
+TEST_F(BoundSessionCookieControllerImplTest, SuccessiveRequestTimeout) {
+  ASSERT_FALSE(IsConnectionTypeAvailableAndOffline());
+  size_t successive_timeout = 5;
+  for (size_t i = 0; i < successive_timeout; i++) {
+    base::test::TestFuture<void> future;
+    bound_session_cookie_controller()->HandleRequestBlockedOnCookie(
+        future.GetCallback());
+    ASSERT_FALSE(future.IsReady());
+    task_environment()->FastForwardBy(kResumeBlockedRequestTimeout);
+    ASSERT_TRUE(future.IsReady());
+  }
+  bound_session_cookie_controller()->HandleRequestBlockedOnCookie(
+      base::DoNothing());
+  ASSERT_TRUE(CompletePendingRefreshRequestIfAny());
+  histogram_tester()->ExpectUniqueSample(
+      "Signin.BoundSessionCredentials.ThrottledRequestsSuccessiveTimeout", 5,
+      1);
+}
+
+TEST_F(BoundSessionCookieControllerImplTest, SuccessiveRequestTimeoutReset) {
+  ASSERT_FALSE(IsConnectionTypeAvailableAndOffline());
+  base::test::TestFuture<void> future;
+  bound_session_cookie_controller()->HandleRequestBlockedOnCookie(
+      future.GetCallback());
+  ASSERT_FALSE(future.IsReady());
+  task_environment()->FastForwardBy(kResumeBlockedRequestTimeout);
+  ASSERT_TRUE(future.IsReady());
+
+  bound_session_cookie_controller()->HandleRequestBlockedOnCookie(
+      base::DoNothing());
+  ASSERT_TRUE(CompletePendingRefreshRequestIfAny());
+  histogram_tester()->ExpectUniqueSample(
+      "Signin.BoundSessionCredentials.ThrottledRequestsSuccessiveTimeout", 1,
+      1);
+
+  task_environment()->FastForwardBy(base::Minutes(10));
+  ASSERT_FALSE(AreAllCookiesFresh());
+  bound_session_cookie_controller()->HandleRequestBlockedOnCookie(
+      base::DoNothing());
+  task_environment()->FastForwardBy(kResumeBlockedRequestTimeout);
+  ResetBoundSessionCookieController();
+  histogram_tester()->ExpectUniqueSample(
+      "Signin.BoundSessionCredentials.ThrottledRequestsSuccessiveTimeout", 1,
+      2);
 }
 
 TEST_F(BoundSessionCookieControllerImplTest,
diff --git a/chrome/browser/signin/chrome_signin_client.cc b/chrome/browser/signin/chrome_signin_client.cc
index 452214f..5e56239 100644
--- a/chrome/browser/signin/chrome_signin_client.cc
+++ b/chrome/browser/signin/chrome_signin_client.cc
@@ -11,10 +11,13 @@
 #include <utility>
 
 #include "base/functional/bind.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/strings/strcat.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "build/buildflag.h"
 #include "build/chromeos_buildflags.h"
+#include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/content_settings/cookie_settings_factory.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
@@ -32,16 +35,21 @@
 #include "chrome/common/buildflags.h"
 #include "chrome/common/channel_info.h"
 #include "chrome/common/pref_names.h"
+#include "components/bookmarks/browser/bookmark_model.h"
+#include "components/bookmarks/browser/url_and_title.h"
 #include "components/content_settings/core/browser/cookie_settings.h"
 #include "components/metrics/metrics_service.h"
 #include "components/policy/core/browser/browser_policy_connector.h"
 #include "components/prefs/pref_service.h"
 #include "components/signin/core/browser/cookie_settings_util.h"
+#include "components/signin/public/base/consent_level.h"
 #include "components/signin/public/base/signin_buildflags.h"
 #include "components/signin/public/base/signin_client.h"
+#include "components/signin/public/base/signin_metrics.h"
 #include "components/signin/public/base/signin_pref_names.h"
 #include "components/signin/public/identity_manager/access_token_info.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
+#include "components/signin/public/identity_manager/primary_account_change_event.h"
 #include "components/signin/public/identity_manager/scope_set.h"
 #include "components/supervised_user/core/common/buildflags.h"
 #include "components/version_info/channel.h"
@@ -49,6 +57,7 @@
 #include "content/public/browser/storage_partition.h"
 #include "google_apis/gaia/gaia_constants.h"
 #include "google_apis/gaia/gaia_urls.h"
+#include "ui/base/models/tree_node_iterator.h"
 #include "url/gurl.h"
 
 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
@@ -107,6 +116,56 @@
         kUserClickedSignoutFromUserPolicyNotificationDialog,
 };
 
+// Returns the histogram suffix name per group of `signin_metrics::AccessPoint`.
+std::string_view NameOfGroupedAccessPointHistogram(
+    signin_metrics::AccessPoint access_point) {
+  switch (access_point) {
+    case signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN:
+      return ".PreUnoWebSignin";
+    case signin_metrics::AccessPoint::
+        ACCESS_POINT_CHROME_SIGNIN_INTERCEPT_BUBBLE:
+      return ".UnoSigninBubble";
+    case signin_metrics::AccessPoint::ACCESS_POINT_USER_MANAGER:
+    case signin_metrics::AccessPoint::ACCESS_POINT_FOR_YOU_FRE:
+    case signin_metrics::AccessPoint::
+        ACCESS_POINT_SIGNIN_INTERCEPT_FIRST_RUN_EXPERIENCE:
+    case signin_metrics::AccessPoint::ACCESS_POINT_START_PAGE:
+      return ".ProfileCreation";
+    case signin_metrics::AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN:
+      return ".ProfileMenu";
+    default:
+      return ".Other";
+  }
+}
+
+void RecordBookmarksCounts(signin_metrics::AccessPoint access_point,
+                           signin::ConsentLevel consent_level,
+                           size_t all_bookmarks_count,
+                           size_t bar_bookmarks_count) {
+  static constexpr std::string_view kBaseHistogramName = "Signin.Bookmarks";
+
+  std::string_view consent_level_token =
+      consent_level == signin::ConsentLevel::kSignin ? ".OnSignin" : ".OnSync";
+
+  std::string all_bookmarks_histogram_name =
+      base::StrCat({kBaseHistogramName, consent_level_token, ".AllBookmarks"});
+  base::UmaHistogramCounts1000(all_bookmarks_histogram_name,
+                               all_bookmarks_count);
+  base::UmaHistogramCounts1000(
+      base::StrCat({all_bookmarks_histogram_name,
+                    NameOfGroupedAccessPointHistogram(access_point)}),
+      all_bookmarks_count);
+
+  std::string bar_bookmarks_histogram_name =
+      base::StrCat({kBaseHistogramName, consent_level_token, ".BookmarksBar"});
+  base::UmaHistogramCounts1000(bar_bookmarks_histogram_name,
+                               bar_bookmarks_count);
+  base::UmaHistogramCounts1000(
+      base::StrCat({bar_bookmarks_histogram_name,
+                    NameOfGroupedAccessPointHistogram(access_point)}),
+      bar_bookmarks_count);
+}
+
 }  // namespace
 
 ChromeSigninClient::ChromeSigninClient(Profile* profile)
@@ -256,6 +315,34 @@
   return chrome::GetChannel();
 }
 
+void ChromeSigninClient::OnPrimaryAccountChangedWithEventSource(
+    signin::PrimaryAccountChangeEvent event_details,
+    absl::variant<signin_metrics::AccessPoint, signin_metrics::ProfileSignout>
+        event_source) {
+  for (signin::ConsentLevel consent_level :
+       {signin::ConsentLevel::kSignin, signin::ConsentLevel::kSync}) {
+    switch (event_details.GetEventTypeFor(consent_level)) {
+      case signin::PrimaryAccountChangeEvent::Type::kNone:
+      case signin::PrimaryAccountChangeEvent::Type::kCleared:
+        // Only record metrics when setting the primary account.
+        break;
+      case signin::PrimaryAccountChangeEvent::Type::kSet:
+        CHECK(
+            absl::holds_alternative<signin_metrics::AccessPoint>(event_source));
+        absl::optional<size_t> all_bookmarks_count = GetAllBookmarksCount();
+        absl::optional<size_t> bar_bookmarks_count =
+            GetBookmarkBarBookmarksCount();
+        if (all_bookmarks_count.has_value() &&
+            bar_bookmarks_count.has_value()) {
+          RecordBookmarksCounts(
+              absl::get<signin_metrics::AccessPoint>(event_source),
+              consent_level, all_bookmarks_count.value(),
+              bar_bookmarks_count.value());
+        }
+    }
+  }
+}
+
 SigninClient::SignoutDecision ChromeSigninClient::GetSignoutDecision(
     bool has_sync_account,
     const absl::optional<signin_metrics::ProfileSignout> signout_source) const {
@@ -344,6 +431,41 @@
 }
 #endif
 
+absl::optional<size_t> ChromeSigninClient::GetAllBookmarksCount() {
+  bookmarks::BookmarkModel* bookmarks =
+      BookmarkModelFactory::GetForBrowserContext(profile_);
+  if (!bookmarks || !bookmarks->root_node()) {
+    return absl::nullopt;
+  }
+
+  // Recursive traversal of the root node, counting URLs only.
+  size_t count = 0;
+  ui::TreeNodeIterator<const bookmarks::BookmarkNode> iterator(
+      bookmarks->root_node());
+  while (iterator.has_next()) {
+    const bookmarks::BookmarkNode* const node = iterator.Next();
+    // Skip folders.
+    if (node->is_url()) {
+      ++count;
+    }
+  }
+  return count;
+}
+
+absl::optional<size_t> ChromeSigninClient::GetBookmarkBarBookmarksCount() {
+  bookmarks::BookmarkModel* bookmarks =
+      BookmarkModelFactory::GetForBrowserContext(profile_);
+  if (!bookmarks || !bookmarks->bookmark_bar_node()) {
+    return absl::nullopt;
+  }
+
+  // It is intended that we only count the visible bookmarks on the bar, meaning
+  // we are not interested in the bookmarks within a folder or subfolder of the
+  // bar. Counting the children only gets us the first layer that appears on the
+  // bar which is the count we need (Note: a folder on that layer counts as 1).
+  return bookmarks->bookmark_bar_node()->children().size();
+}
+
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
 // Returns the account that must be auto-signed-in to the Main Profile in
 // Lacros.
diff --git a/chrome/browser/signin/chrome_signin_client.h b/chrome/browser/signin/chrome_signin_client.h
index d2a51ec6..8639d2da 100644
--- a/chrome/browser/signin/chrome_signin_client.h
+++ b/chrome/browser/signin/chrome_signin_client.h
@@ -76,6 +76,10 @@
       GaiaAuthConsumer* consumer,
       gaia::GaiaSource source) override;
   version_info::Channel GetClientChannel() override;
+  void OnPrimaryAccountChangedWithEventSource(
+      signin::PrimaryAccountChangeEvent event_details,
+      absl::variant<signin_metrics::AccessPoint, signin_metrics::ProfileSignout>
+          event_source) override;
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
   absl::optional<account_manager::Account> GetInitialPrimaryAccount() override;
@@ -116,6 +120,12 @@
   void OnTokenFetchComplete(bool token_is_valid);
 #endif
 
+  // virtual for unit testing: cut down dependency on `BookmarkModel`.
+  // The following two functions will return `absl::nullopt` if the
+  // `BookmarkModel` is nullptr.
+  virtual absl::optional<size_t> GetAllBookmarksCount();
+  virtual absl::optional<size_t> GetBookmarkBarBookmarksCount();
+
   const std::unique_ptr<WaitForNetworkCallbackHelper>
       wait_for_network_callback_helper_;
   raw_ptr<Profile, DanglingUntriaged> profile_;
diff --git a/chrome/browser/signin/chrome_signin_client_browsertest.cc b/chrome/browser/signin/chrome_signin_client_browsertest.cc
new file mode 100644
index 0000000..83ac722ae
--- /dev/null
+++ b/chrome/browser/signin/chrome_signin_client_browsertest.cc
@@ -0,0 +1,138 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/bookmarks/bookmark_model_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/identity_manager_factory.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "components/bookmarks/browser/bookmark_model.h"
+#include "components/bookmarks/browser/bookmark_node.h"
+#include "components/signin/public/base/consent_level.h"
+#include "components/signin/public/identity_manager/identity_manager.h"
+#include "components/signin/public/identity_manager/identity_test_utils.h"
+#include "content/public/test/browser_test.h"
+#include "url/gurl.h"
+
+class ChromeSigninClientBrowserTest : public InProcessBrowserTest {};
+
+// This test is intended to make sure the count of bookmarks is done accurately.
+IN_PROC_BROWSER_TEST_F(ChromeSigninClientBrowserTest,
+                       BookmarksMetricsRecordOnSignin) {
+  base::HistogramTester histogram_tester;
+
+  bookmarks::BookmarkModel* bookmark_model =
+      BookmarkModelFactory::GetForBrowserContext(browser()->profile());
+
+  // Constructing the bookmark graph.
+
+  // These two URLs are used twice to make sure they are counted twice as well.
+  GURL url1("http://url1");
+  GURL url4("http://url4");
+  const bookmarks::BookmarkNode* bookmark_bar =
+      bookmark_model->bookmark_bar_node();
+  bookmark_model->AddURL(bookmark_bar, bookmark_bar->children().size(),
+                         u"bookmark_bar_URL_1", url1);
+  const bookmarks::BookmarkNode* bar_folder = bookmark_model->AddFolder(
+      bookmark_bar, bookmark_bar->children().size(), u"bar_folder_1");
+  bookmark_model->AddURL(bookmark_bar, bookmark_bar->children().size(),
+                         u"bookmark_bar_URL_2", GURL("http://url2"));
+
+  bookmark_model->AddURL(bar_folder, bar_folder->children().size(),
+                         u"bar_URL_1", url4);
+  const bookmarks::BookmarkNode* bar_sub_folder = bookmark_model->AddFolder(
+      bar_folder, bar_folder->children().size(), u"bar_sub_folder");
+  bookmark_model->AddURL(bar_sub_folder, bar_sub_folder->children().size(),
+                         u"bar_sub_folderURL_1", url1);
+
+  const bookmarks::BookmarkNode* other_bookmarks = bookmark_model->other_node();
+  const bookmarks::BookmarkNode* other_folder = bookmark_model->AddFolder(
+      other_bookmarks, other_bookmarks->children().size(), u"other_folder_1");
+  bookmark_model->AddURL(other_bookmarks, other_bookmarks->children().size(),
+                         u"other_URL_1", GURL("http://url3"));
+  bookmark_model->AddURL(other_folder, other_folder->children().size(),
+                         u"other_folder_URL_1", url4);
+
+  // Bookmark graph:
+  //
+  // Bookmark Bar
+  // |- bookmark_bar_URL_1 (url1)
+  // |_ bar_folder_1
+  // |  |_ bar_URL_1 (url4)
+  // |  |_ bar_sub_folder
+  // |  |  |- bar_sub_folderURL_1 (url1)
+  // |_ bookmark_bar_URL_2 (url2)
+  // Other Bookmarks
+  // |_ other_folder_1
+  // |  |- other_folder_URL_1 (url4)
+  // |_ other_URL_1 (url3)
+
+  // Given the graph above:
+  //
+  // Count all bookmarks (even duplicates, without folders).
+  size_t expected_all_bookmarks_count = 6;
+  // Count only first layer of the bookmark bar (including folders).
+  size_t expected_bar_bookmarks_count = 3;
+
+  // Sign in to Chrome.
+  const std::string email = "alice@example.com";
+  signin::IdentityManager* identity_manager =
+      IdentityManagerFactory::GetForProfile(browser()->profile());
+  signin::MakePrimaryAccountAvailable(identity_manager, email,
+                                      signin::ConsentLevel::kSignin);
+
+  // Test signin histogram expectations.
+  histogram_tester.ExpectUniqueSample("Signin.Bookmarks.OnSignin.AllBookmarks",
+                                      expected_all_bookmarks_count, 1);
+  histogram_tester.ExpectUniqueSample("Signin.Bookmarks.OnSignin.BookmarksBar",
+                                      expected_bar_bookmarks_count, 1);
+  histogram_tester.ExpectUniqueSample(
+      "Signin.Bookmarks.OnSignin.AllBookmarks.Other",
+      expected_all_bookmarks_count, 1);
+  histogram_tester.ExpectUniqueSample(
+      "Signin.Bookmarks.OnSignin.BookmarksBar.Other",
+      expected_bar_bookmarks_count, 1);
+  // No values expected for sync.
+  base::HistogramTester::CountsMap expected_sync_counts;
+  EXPECT_THAT(
+      histogram_tester.GetTotalCountsForPrefix("Signin.Bookmarks.OnSync"),
+      testing::ContainerEq(expected_sync_counts));
+
+  //----------------------------------------------------------------------------
+
+  // Add 2 empty folders before syncing.
+  bookmark_model->AddFolder(bookmark_bar, bookmark_bar->children().size(),
+                            u"bar_folder_2");
+  // Should expect 1 more count for the bar bookmarks histograms.
+  size_t sync_expected_bar_bookmarks_count_count =
+      expected_bar_bookmarks_count + 1;
+  // But not for the all bookmarks count.
+  bookmark_model->AddFolder(other_bookmarks, other_bookmarks->children().size(),
+                            u"other_folder_1");
+
+  // New histogram tester for easier new values check.
+  base::HistogramTester histogram_tester_sync;
+  // Enable Sync.
+  signin::MakePrimaryAccountAvailable(identity_manager, email,
+                                      signin::ConsentLevel::kSync);
+
+  // Test sync histogram expectations.
+  histogram_tester.ExpectUniqueSample("Signin.Bookmarks.OnSync.AllBookmarks",
+                                      expected_all_bookmarks_count, 1);
+  histogram_tester.ExpectUniqueSample("Signin.Bookmarks.OnSync.BookmarksBar",
+                                      sync_expected_bar_bookmarks_count_count,
+                                      1);
+  histogram_tester.ExpectUniqueSample(
+      "Signin.Bookmarks.OnSync.AllBookmarks.Other",
+      expected_all_bookmarks_count, 1);
+  histogram_tester.ExpectUniqueSample(
+      "Signin.Bookmarks.OnSync.BookmarksBar.Other",
+      sync_expected_bar_bookmarks_count_count, 1);
+
+  // No new values expected for Signin histograms.
+  base::HistogramTester::CountsMap expected_signin_counts;
+  EXPECT_THAT(
+      histogram_tester_sync.GetTotalCountsForPrefix("Signin.Bookmarks.OnSign"),
+      testing::ContainerEq(expected_signin_counts));
+}
diff --git a/chrome/browser/signin/chrome_signin_client_factory.cc b/chrome/browser/signin/chrome_signin_client_factory.cc
index b5fd298..3170b5779 100644
--- a/chrome/browser/signin/chrome_signin_client_factory.cc
+++ b/chrome/browser/signin/chrome_signin_client_factory.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/signin/chrome_signin_client_factory.h"
 
+#include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/net/profile_network_context_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 
@@ -17,6 +18,8 @@
               .WithGuest(ProfileSelection::kOriginalOnly)
               .Build()) {
   DependsOn(ProfileNetworkContextServiceFactory::GetInstance());
+  // Used to keep track of bookmark metrics on Signin/Sync.
+  DependsOn(BookmarkModelFactory::GetInstance());
 }
 
 ChromeSigninClientFactory::~ChromeSigninClientFactory() = default;
diff --git a/chrome/browser/signin/chrome_signin_client_unittest.cc b/chrome/browser/signin/chrome_signin_client_unittest.cc
index 2a7bb5c..950e1aa 100644
--- a/chrome/browser/signin/chrome_signin_client_unittest.cc
+++ b/chrome/browser/signin/chrome_signin_client_unittest.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "base/functional/bind.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/browser_process.h"
@@ -21,8 +22,10 @@
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
 #include "components/prefs/pref_service.h"
+#include "components/signin/public/base/consent_level.h"
 #include "components/signin/public/base/signin_metrics.h"
 #include "components/signin/public/base/signin_pref_names.h"
+#include "components/signin/public/identity_manager/account_info.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "components/signin/public/identity_manager/identity_test_environment.h"
 #include "components/supervised_user/core/common/buildflags.h"
@@ -47,6 +50,9 @@
                void(signin_metrics::ProfileSignout,
                     signin_metrics::SignoutDelete,
                     SigninClient::SignoutDecision signout_decision));
+
+  MOCK_METHOD0(GetAllBookmarksCount, absl::optional<size_t>());
+  MOCK_METHOD0(GetBookmarkBarBookmarksCount, absl::optional<size_t>());
 };
 
 class ChromeSigninClientSignoutTest : public BrowserWithTestWindowTest {
@@ -368,4 +374,406 @@
                          ChromeSigninClientSignoutSourceTest,
                          testing::ValuesIn(kSignoutSources));
 
+struct BookmarkAccessPointHistogramNamesParam {
+  signin_metrics::AccessPoint access_point;
+  std::string all_bookmarks_signin_histogram_name;
+  std::string bar_bookmarks_signin_histogram_name;
+  std::string all_bookmarks_sync_histogram_name;
+  std::string bar_bookmarks_sync_histogram_name;
+
+  std::string suffix_test_name;
+};
+
+// Expected values for each access point group.
+const BookmarkAccessPointHistogramNamesParam params_per_access_point_group[] = {
+    // Expecting 'PreUnoWebSignin'.
+    {.access_point = signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN,
+     .all_bookmarks_signin_histogram_name =
+         "Signin.Bookmarks.OnSignin.AllBookmarks.PreUnoWebSignin",
+     .bar_bookmarks_signin_histogram_name =
+         "Signin.Bookmarks.OnSignin.BookmarksBar.PreUnoWebSignin",
+     .all_bookmarks_sync_histogram_name =
+         "Signin.Bookmarks.OnSync.AllBookmarks.PreUnoWebSignin",
+     .bar_bookmarks_sync_histogram_name =
+         "Signin.Bookmarks.OnSync.BookmarksBar.PreUnoWebSignin",
+     .suffix_test_name = "AccessPointGroup_PreUnoWebSignin"},
+
+    // Expecting 'UnoSigninBubble'.
+    {.access_point = signin_metrics::AccessPoint::
+         ACCESS_POINT_CHROME_SIGNIN_INTERCEPT_BUBBLE,
+     .all_bookmarks_signin_histogram_name =
+         "Signin.Bookmarks.OnSignin.AllBookmarks.UnoSigninBubble",
+     .bar_bookmarks_signin_histogram_name =
+         "Signin.Bookmarks.OnSignin.BookmarksBar.UnoSigninBubble",
+     .all_bookmarks_sync_histogram_name =
+         "Signin.Bookmarks.OnSync.AllBookmarks.UnoSigninBubble",
+     .bar_bookmarks_sync_histogram_name =
+         "Signin.Bookmarks.OnSync.BookmarksBar.UnoSigninBubble",
+     .suffix_test_name = "AccessPointGroup_UnoSigninBubble"},
+
+    // Expecting 'ProfileCreation'.
+    {.access_point = signin_metrics::AccessPoint::ACCESS_POINT_USER_MANAGER,
+     .all_bookmarks_signin_histogram_name =
+         "Signin.Bookmarks.OnSignin.AllBookmarks.ProfileCreation",
+     .bar_bookmarks_signin_histogram_name =
+         "Signin.Bookmarks.OnSignin.BookmarksBar.ProfileCreation",
+     .all_bookmarks_sync_histogram_name =
+         "Signin.Bookmarks.OnSync.AllBookmarks.ProfileCreation",
+     .bar_bookmarks_sync_histogram_name =
+         "Signin.Bookmarks.OnSync.BookmarksBar.ProfileCreation",
+     .suffix_test_name = "AccessPointGroup_ProfileCreation"},
+
+    // Expecting 'ProfileMenu'.
+    {.access_point =
+         signin_metrics::AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN,
+     .all_bookmarks_signin_histogram_name =
+         "Signin.Bookmarks.OnSignin.AllBookmarks.ProfileMenu",
+     .bar_bookmarks_signin_histogram_name =
+         "Signin.Bookmarks.OnSignin.BookmarksBar.ProfileMenu",
+     .all_bookmarks_sync_histogram_name =
+         "Signin.Bookmarks.OnSync.AllBookmarks.ProfileMenu",
+     .bar_bookmarks_sync_histogram_name =
+         "Signin.Bookmarks.OnSync.BookmarksBar.ProfileMenu",
+     .suffix_test_name = "AccessPointGroup_ProfileMenu"},
+
+    // Expecting 'Other'.
+    {.access_point = signin_metrics::AccessPoint::ACCESS_POINT_EXTENSIONS,
+     .all_bookmarks_signin_histogram_name =
+         "Signin.Bookmarks.OnSignin.AllBookmarks.Other",
+     .bar_bookmarks_signin_histogram_name =
+         "Signin.Bookmarks.OnSignin.BookmarksBar.Other",
+     .all_bookmarks_sync_histogram_name =
+         "Signin.Bookmarks.OnSync.AllBookmarks.Other",
+     .bar_bookmarks_sync_histogram_name =
+         "Signin.Bookmarks.OnSync.BookmarksBar.Other",
+     .suffix_test_name = "AccessPointGroup_Other"},
+};
+
+// Helper to have a better parametrized test.
+std::string ParamToTestSuffix(
+    const ::testing::TestParamInfo<
+        std::tuple<signin::ConsentLevel,
+                   BookmarkAccessPointHistogramNamesParam>>& info) {
+  std::string consent_level_string =
+      std::get<0>(info.param) == signin::ConsentLevel::kSignin ? "Signin"
+                                                               : "Sync";
+  return consent_level_string + "_" + std::get<1>(info.param).suffix_test_name;
+}
+
+class ChromeSigninClientMetricsTest
+    : public ::testing::TestWithParam<
+          std::tuple<signin::ConsentLevel,
+                     BookmarkAccessPointHistogramNamesParam>> {
+ public:
+  TestingProfile* profile() { return testing_profile_.get(); }
+
+  const base::HistogramTester& histogram_tester() { return histogram_tester_; }
+
+  // Checks both AllBookmarks and BookmarksBar histograms with no access point.
+  void ExpectSigninBookmarksHistogramValues(size_t expected_all_bookmark_count,
+                                            size_t expected_bar_bookmarks_count,
+                                            size_t signin_expected_bucket_count,
+                                            size_t sync_expected_bucket_count) {
+    histogram_tester_.ExpectUniqueSample(
+        "Signin.Bookmarks.OnSignin.AllBookmarks", expected_all_bookmark_count,
+        signin_expected_bucket_count);
+    histogram_tester_.ExpectUniqueSample(
+        "Signin.Bookmarks.OnSignin.BookmarksBar", expected_bar_bookmarks_count,
+        signin_expected_bucket_count);
+
+    histogram_tester_.ExpectUniqueSample("Signin.Bookmarks.OnSync.AllBookmarks",
+                                         expected_all_bookmark_count,
+                                         sync_expected_bucket_count);
+    histogram_tester_.ExpectUniqueSample("Signin.Bookmarks.OnSync.BookmarksBar",
+                                         expected_bar_bookmarks_count,
+                                         sync_expected_bucket_count);
+  }
+
+ private:
+  content::BrowserTaskEnvironment task_environment_;
+  std::unique_ptr<TestingProfile> testing_profile_ =
+      TestingProfile::Builder().Build();
+  base::HistogramTester histogram_tester_;
+};
+
+TEST_P(ChromeSigninClientMetricsTest, BookmarkCount) {
+  MockChromeSigninClient client(profile());
+  const size_t all_bookmarks_count = 5;
+  const size_t bar_bookmarks_count = 3;
+
+  EXPECT_CALL(client, GetAllBookmarksCount())
+      .WillOnce(testing::Return(all_bookmarks_count));
+  EXPECT_CALL(client, GetBookmarkBarBookmarksCount())
+      .WillOnce(testing::Return(bar_bookmarks_count));
+
+  CoreAccountInfo account;
+  account.email = "example@example.com";
+  account.gaia = "gaia_example";
+  ASSERT_FALSE(account.IsEmpty());
+
+  signin::ConsentLevel consent_level = std::get<0>(GetParam());
+  signin::PrimaryAccountChangeEvent::State previous_state;
+  // When testing for `kSync`, simulate a previous state with the same account
+  // having `kSignin`.
+  // A separate test is done for a direct change to `kSync`:
+  // `BookmarkCountWithAccountInSyncDirectly`.
+  if (consent_level == signin::ConsentLevel::kSync) {
+    previous_state.primary_account = account;
+    previous_state.consent_level = signin::ConsentLevel::kSignin;
+  }
+  signin::PrimaryAccountChangeEvent event_details{
+      previous_state,
+      /*current_state=*/signin::PrimaryAccountChangeEvent::State(
+          account, consent_level)};
+  // Ensure the events types are correct for both consent levels.
+  if (consent_level == signin::ConsentLevel::kSync) {
+    ASSERT_EQ(event_details.GetEventTypeFor(signin::ConsentLevel::kSignin),
+              signin::PrimaryAccountChangeEvent::Type::kNone);
+    ASSERT_EQ(event_details.GetEventTypeFor(signin::ConsentLevel::kSync),
+              signin::PrimaryAccountChangeEvent::Type::kSet);
+  } else {
+    ASSERT_EQ(event_details.GetEventTypeFor(signin::ConsentLevel::kSignin),
+              signin::PrimaryAccountChangeEvent::Type::kSet);
+    ASSERT_EQ(event_details.GetEventTypeFor(signin::ConsentLevel::kSync),
+              signin::PrimaryAccountChangeEvent::Type::kNone);
+  }
+
+  BookmarkAccessPointHistogramNamesParam test_params = std::get<1>(GetParam());
+  // Simulate primary account changed.
+  client.OnPrimaryAccountChangedWithEventSource(event_details,
+                                                test_params.access_point);
+
+  // Check for expected histograms values below.
+  const size_t signin_expected_bucket_count =
+      consent_level == signin::ConsentLevel::kSignin ? 1 : 0;
+  const size_t sync_expected_bucket_count =
+      consent_level == signin::ConsentLevel::kSync ? 1 : 0;
+
+  // Checks histogram values without access point group names.
+  ExpectSigninBookmarksHistogramValues(all_bookmarks_count, bar_bookmarks_count,
+                                       signin_expected_bucket_count,
+                                       sync_expected_bucket_count);
+
+  // For AllBookmarks with access point group name.
+  histogram_tester().ExpectUniqueSample(
+      test_params.all_bookmarks_signin_histogram_name, all_bookmarks_count,
+      signin_expected_bucket_count);
+  histogram_tester().ExpectUniqueSample(
+      test_params.all_bookmarks_sync_histogram_name, all_bookmarks_count,
+      sync_expected_bucket_count);
+
+  // For BookmarksBar with access point group name.
+  histogram_tester().ExpectUniqueSample(
+      test_params.bar_bookmarks_signin_histogram_name, bar_bookmarks_count,
+      signin_expected_bucket_count);
+  histogram_tester().ExpectUniqueSample(
+      test_params.bar_bookmarks_sync_histogram_name, bar_bookmarks_count,
+      sync_expected_bucket_count);
+
+  // The exact counts makes sure that no other histograms within this family
+  // records unwanted values. For example not recording Sync histograms with a
+  // Signin event and vice versa, or histogram for different access points than
+  // the one being tested.
+  // Exact sample counts histograms are done above.
+  base::HistogramTester::CountsMap expected_counts;
+  if (consent_level == signin::ConsentLevel::kSignin) {
+    expected_counts["Signin.Bookmarks.OnSignin.AllBookmarks"] = 1;
+    expected_counts["Signin.Bookmarks.OnSignin.BookmarksBar"] = 1;
+    expected_counts[test_params.all_bookmarks_signin_histogram_name] = 1;
+    expected_counts[test_params.bar_bookmarks_signin_histogram_name] = 1;
+  } else if (consent_level == signin::ConsentLevel::kSync) {
+    expected_counts["Signin.Bookmarks.OnSync.AllBookmarks"] = 1;
+    expected_counts["Signin.Bookmarks.OnSync.BookmarksBar"] = 1;
+    expected_counts[test_params.all_bookmarks_sync_histogram_name] = 1;
+    expected_counts[test_params.bar_bookmarks_sync_histogram_name] = 1;
+  }
+  EXPECT_THAT(histogram_tester().GetTotalCountsForPrefix("Signin.Bookmarks."),
+              testing::ContainerEq(expected_counts));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    ,
+    ChromeSigninClientMetricsTest,
+    testing::Combine(testing::ValuesIn({signin::ConsentLevel::kSignin,
+                                        signin::ConsentLevel::kSync}),
+                     testing::ValuesIn(params_per_access_point_group)),
+    &ParamToTestSuffix);
+
+// In this test, the account changes is directly set to `kSync`, without a prior
+// state where `kSignin` is set, this will trigger both changes for `kSignin`
+// and `kSync`, only testing a single access point.
+TEST_F(ChromeSigninClientMetricsTest, BookmarkCountWithAccountInSyncDirectly) {
+  MockChromeSigninClient client(profile());
+  const size_t all_bookmarks_count = 7;
+  const size_t bar_bookmarks_count = 5;
+
+  // `Times(2)` for both Signin then Sync.
+  EXPECT_CALL(client, GetAllBookmarksCount())
+      .Times(2)
+      .WillRepeatedly(testing::Return(all_bookmarks_count));
+  EXPECT_CALL(client, GetBookmarkBarBookmarksCount())
+      .Times(2)
+      .WillRepeatedly(testing::Return(bar_bookmarks_count));
+
+  CoreAccountInfo account;
+  account.email = "example@example.com";
+  account.gaia = "gaia_example";
+  ASSERT_FALSE(account.IsEmpty());
+
+  // State goes from no account to an account with `kSync` set.
+  // It will trigger both events to `kSignin` and `kSync`.
+  signin::PrimaryAccountChangeEvent event_details{
+      /*previous_state=*/signin::PrimaryAccountChangeEvent::State(),
+      /*current_state=*/signin::PrimaryAccountChangeEvent::State(
+          account, signin::ConsentLevel::kSync)};
+  // Both Signin and Sync event are being set.
+  ASSERT_EQ(event_details.GetEventTypeFor(signin::ConsentLevel::kSignin),
+            signin::PrimaryAccountChangeEvent::Type::kSet);
+  ASSERT_EQ(event_details.GetEventTypeFor(signin::ConsentLevel::kSync),
+            signin::PrimaryAccountChangeEvent::Type::kSet);
+
+  // Simulate primary account changed.
+  client.OnPrimaryAccountChangedWithEventSource(
+      event_details, signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN);
+
+  // Check for expected histograms values below.
+
+  // Checks histogram values without access point group names.
+  histogram_tester().ExpectUniqueSample(
+      "Signin.Bookmarks.OnSignin.AllBookmarks", all_bookmarks_count, 1);
+  histogram_tester().ExpectUniqueSample("Signin.Bookmarks.OnSync.AllBookmarks",
+                                        all_bookmarks_count, 1);
+  histogram_tester().ExpectUniqueSample(
+      "Signin.Bookmarks.OnSignin.BookmarksBar", bar_bookmarks_count, 1);
+  histogram_tester().ExpectUniqueSample("Signin.Bookmarks.OnSync.BookmarksBar",
+                                        bar_bookmarks_count, 1);
+
+  // For AllBookmarks with access point group name.
+  histogram_tester().ExpectUniqueSample(
+      "Signin.Bookmarks.OnSignin.AllBookmarks.PreUnoWebSignin",
+      all_bookmarks_count, 1);
+  histogram_tester().ExpectUniqueSample(
+      "Signin.Bookmarks.OnSync.AllBookmarks.PreUnoWebSignin",
+      all_bookmarks_count, 1);
+
+  // For BookmarksBar with access point group name.
+  histogram_tester().ExpectUniqueSample(
+      "Signin.Bookmarks.OnSignin.BookmarksBar.PreUnoWebSignin",
+      bar_bookmarks_count, 1);
+  histogram_tester().ExpectUniqueSample(
+      "Signin.Bookmarks.OnSync.BookmarksBar.PreUnoWebSignin",
+      bar_bookmarks_count, 1);
+
+  // Makes sure that no other unwanted histograms are recorded (Mainly for
+  // other access point groups). Exact sample counts are checked above.
+  base::HistogramTester::CountsMap expected_counts;
+  expected_counts["Signin.Bookmarks.OnSignin.AllBookmarks"] = 1;
+  expected_counts["Signin.Bookmarks.OnSignin.BookmarksBar"] = 1;
+  expected_counts["Signin.Bookmarks.OnSync.AllBookmarks"] = 1;
+  expected_counts["Signin.Bookmarks.OnSync.BookmarksBar"] = 1;
+  expected_counts["Signin.Bookmarks.OnSignin.AllBookmarks.PreUnoWebSignin"] = 1;
+  expected_counts["Signin.Bookmarks.OnSignin.BookmarksBar.PreUnoWebSignin"] = 1;
+  expected_counts["Signin.Bookmarks.OnSync.AllBookmarks.PreUnoWebSignin"] = 1;
+  expected_counts["Signin.Bookmarks.OnSync.BookmarksBar.PreUnoWebSignin"] = 1;
+  EXPECT_THAT(histogram_tester().GetTotalCountsForPrefix("Signin.Bookmarks."),
+              testing::ContainerEq(expected_counts));
+}
+
+// Not expecting any histogram to be recorded when no account update happens.
+TEST_F(ChromeSigninClientMetricsTest, BookmarkCountWithAccountUpdate_kNone) {
+  MockChromeSigninClient client(profile());
+
+  EXPECT_CALL(client, GetAllBookmarksCount()).Times(0);
+  EXPECT_CALL(client, GetBookmarkBarBookmarksCount()).Times(0);
+
+  // Event details to simulate no update. Either empty or same value set.
+  signin::PrimaryAccountChangeEvent event_details{
+      /*previous_state=*/signin::PrimaryAccountChangeEvent::State(),
+      /*current_state=*/signin::PrimaryAccountChangeEvent::State()};
+  ASSERT_EQ(event_details.GetEventTypeFor(signin::ConsentLevel::kSignin),
+            signin::PrimaryAccountChangeEvent::Type::kNone);
+  ASSERT_EQ(event_details.GetEventTypeFor(signin::ConsentLevel::kSync),
+            signin::PrimaryAccountChangeEvent::Type::kNone);
+
+  // Simulate primary account changed.
+  client.OnPrimaryAccountChangedWithEventSource(
+      event_details, signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN);
+
+  // `expected_counts` is empty as we expect no histograms related to
+  // `Signin.Bookmarks` to be recorded.
+  base::HistogramTester::CountsMap expected_counts;
+  EXPECT_THAT(histogram_tester().GetTotalCountsForPrefix("Signin.Bookmarks."),
+              testing::ContainerEq(expected_counts));
+}
+
+// Not expecting any histogram to be recorded when revoking account consent.
+TEST_F(ChromeSigninClientMetricsTest, BookmarkCountWithAccountUpdate_kCleared) {
+  MockChromeSigninClient client(profile());
+
+  EXPECT_CALL(client, GetAllBookmarksCount()).Times(0);
+  EXPECT_CALL(client, GetBookmarkBarBookmarksCount()).Times(0);
+
+  CoreAccountInfo account;
+  account.email = "example@example.com";
+  account.gaia = "gaia_example";
+  ASSERT_FALSE(account.IsEmpty());
+
+  // Simulating revoking Signin consent.
+  signin::PrimaryAccountChangeEvent event_details{
+      /*previous_state=*/signin::PrimaryAccountChangeEvent::State(
+          account, signin::ConsentLevel::kSignin),
+      /*current_state=*/signin::PrimaryAccountChangeEvent::State()};
+  ASSERT_EQ(event_details.GetEventTypeFor(signin::ConsentLevel::kSignin),
+            signin::PrimaryAccountChangeEvent::Type::kCleared);
+  ASSERT_EQ(event_details.GetEventTypeFor(signin::ConsentLevel::kSync),
+            signin::PrimaryAccountChangeEvent::Type::kNone);
+
+  // Simulate primary account changed.
+  client.OnPrimaryAccountChangedWithEventSource(
+      event_details, signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN);
+
+  // `expected_counts` is empty as we expect no histograms related to
+  // `Signin.Bookmarks` to be recorded.
+  base::HistogramTester::CountsMap expected_counts;
+  EXPECT_THAT(histogram_tester().GetTotalCountsForPrefix("Signin.Bookmarks."),
+              testing::ContainerEq(expected_counts));
+}
+
+// Not expecting any histogram to be recorded when the bookmark service is null.
+TEST_F(ChromeSigninClientMetricsTest,
+       BookmarkCountWithAccountSigningin_ServiceNull) {
+  MockChromeSigninClient client(profile());
+
+  // Returning `absl::nullopt` to simulate the service being nullptr.
+  EXPECT_CALL(client, GetAllBookmarksCount())
+      .WillOnce(testing::Return(absl::nullopt));
+  EXPECT_CALL(client, GetBookmarkBarBookmarksCount())
+      .WillOnce(testing::Return(absl::nullopt));
+
+  CoreAccountInfo account;
+  account.email = "example@example.com";
+  account.gaia = "gaia_example";
+  ASSERT_FALSE(account.IsEmpty());
+
+  // Simulating signing in update.
+  signin::PrimaryAccountChangeEvent event_details{
+      /*previous_state=*/signin::PrimaryAccountChangeEvent::State(),
+      /*current_state=*/signin::PrimaryAccountChangeEvent::State(
+          account, signin::ConsentLevel::kSignin)};
+  ASSERT_EQ(event_details.GetEventTypeFor(signin::ConsentLevel::kSignin),
+            signin::PrimaryAccountChangeEvent::Type::kSet);
+  ASSERT_EQ(event_details.GetEventTypeFor(signin::ConsentLevel::kSync),
+            signin::PrimaryAccountChangeEvent::Type::kNone);
+
+  // Simulate primary account changed.
+  client.OnPrimaryAccountChangedWithEventSource(
+      event_details, signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN);
+
+  // `expected_counts` is empty as we expect no histograms related to
+  // `Signin.Bookmarks` to be recorded despite signing in.
+  base::HistogramTester::CountsMap expected_counts;
+  EXPECT_THAT(histogram_tester().GetTotalCountsForPrefix("Signin.Bookmarks."),
+              testing::ContainerEq(expected_counts));
+}
+
 #endif  // !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID)
diff --git a/chrome/browser/signin/dice_web_signin_interceptor.cc b/chrome/browser/signin/dice_web_signin_interceptor.cc
index 9502d5f..4c23931 100644
--- a/chrome/browser/signin/dice_web_signin_interceptor.cc
+++ b/chrome/browser/signin/dice_web_signin_interceptor.cc
@@ -69,6 +69,7 @@
 #include "components/signin/public/identity_manager/accounts_mutator.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "components/signin/public/identity_manager/primary_account_mutator.h"
+#include "components/signin/public/identity_manager/tribool.h"
 #include "components/supervised_user/core/common/features.h"
 #include "google_apis/gaia/gaia_auth_util.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -122,24 +123,51 @@
           gaia::AreEmailsSame(email, accounts_in_chrome[0].email));
 }
 
-bool ShouldShowChromeSigninBubble(signin::IdentityManager* manager,
-                                  const std::string& email) {
+// If the access_point is not set, this function may return
+// `signin::Tribool::kUnknown`.
+signin::Tribool MaybeShouldShowChromeSigninBubble(
+    signin::IdentityManager* manager,
+    const std::string& email,
+    signin_metrics::AccessPoint access_point) {
   // The Chrome Signin Bubble is part of the Uno Desktop project.
   if (!base::FeatureList::IsEnabled(switches::kUnoDesktop)) {
-    return false;
+    return signin::Tribool::kFalse;
   }
 
   // Check if an account is already signed in to Chrome.
   if (manager->HasPrimaryAccount(signin::ConsentLevel::kSignin)) {
-    return false;
+    return signin::Tribool::kFalse;
   }
 
   // Only show the Chrome Sign in bubble for the first account being signed in.
   if (!IsFirstAccount(manager, email)) {
-    return false;
+    return signin::Tribool::kFalse;
   }
 
-  return true;
+  // If the access point is not set, we cannot accurately know if we have to
+  // show the bubble or not.
+  if (access_point == signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN) {
+    return signin::Tribool::kUnknown;
+  }
+
+  // Only show the Chrome Signin Bubble when the signin event occurred through
+  // a regular web signin in (not triggered through a chrome feature).
+  if (access_point != signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN) {
+    return signin::Tribool::kFalse;
+  }
+
+  return signin::Tribool::kTrue;
+}
+
+// Assumes that if it is unsure to show the bubble or not, then we shouldn't
+// display it.
+bool ShouldShowChromeSigninBubble(signin::IdentityManager* manager,
+                                  const std::string& email,
+                                  signin_metrics::AccessPoint access_point) {
+  signin::Tribool should_show =
+      MaybeShouldShowChromeSigninBubble(manager, email, access_point);
+  return should_show != signin::Tribool::kUnknown &&
+         signin::TriboolToBoolOrDie(should_show);
 }
 
 }  // namespace
@@ -238,9 +266,15 @@
 
   DCHECK(signin_interception_enabled && !enforce_enterprise_separation.value());
 
-  bool is_first_account = IsFirstAccount(identity_manager_, email);
-  if (is_first_account &&
-      ShouldShowChromeSigninBubble(identity_manager_, email)) {
+  signin::Tribool should_show_chrome_signin_bubble =
+      MaybeShouldShowChromeSigninBubble(identity_manager_, email,
+                                        access_point_);
+  // If the access point is not set, it is unclear if we have to show the bubble
+  // or not, so we must return nullopt.
+  if (should_show_chrome_signin_bubble == signin::Tribool::kUnknown) {
+    return absl::nullopt;
+  }
+  if (TriboolToBoolOrDie(should_show_chrome_signin_bubble)) {
     return SigninInterceptionHeuristicOutcome::kInterceptChromeSignin;
   }
 
@@ -250,7 +284,7 @@
     return SigninInterceptionHeuristicOutcome::kAbortProfileCreationDisallowed;
   }
 
-  if (is_first_account) {
+  if (IsFirstAccount(identity_manager_, email)) {
     // Enterprise and multi-user bubbles are only shown if there are multiple
     // accounts. The intercepted account may not be added to chrome yet.
     return SigninInterceptionHeuristicOutcome::kAbortSingleAccount;
@@ -267,6 +301,7 @@
 void DiceWebSigninInterceptor::MaybeInterceptWebSignin(
     content::WebContents* web_contents,
     CoreAccountId account_id,
+    signin_metrics::AccessPoint access_point,
     bool is_new_account,
     bool is_sync_signin) {
   if (is_interception_in_progress_) {
@@ -278,6 +313,7 @@
 
   DCHECK_EQ(interception_start_time_, base::TimeTicks());
   interception_start_time_ = base::TimeTicks::Now();
+  access_point_ = access_point;
 
   if (!web_contents) {
     // The tab has been closed (typically during the token exchange, which may
@@ -682,7 +718,8 @@
         WebSigninInterceptor::SigninInterceptionType::kProfileSwitch;
     RecordSigninInterceptionHeuristicOutcome(
         SigninInterceptionHeuristicOutcome::kInterceptProfileSwitch);
-  } else if (ShouldShowChromeSigninBubble(identity_manager_, info.email)) {
+  } else if (ShouldShowChromeSigninBubble(identity_manager_, info.email,
+                                          access_point_)) {
     interception_type =
         WebSigninInterceptor::SigninInterceptionType::kChromeSignin;
     RecordSigninInterceptionHeuristicOutcome(
diff --git a/chrome/browser/signin/dice_web_signin_interceptor.h b/chrome/browser/signin/dice_web_signin_interceptor.h
index 8cceb6a..756f475e 100644
--- a/chrome/browser/signin/dice_web_signin_interceptor.h
+++ b/chrome/browser/signin/dice_web_signin_interceptor.h
@@ -19,6 +19,7 @@
 #include "chrome/browser/ui/webui/signin/signin_utils.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/policy/core/browser/signin/profile_separation_policies.h"
+#include "components/signin/public/base/signin_metrics.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "google_apis/gaia/core_account_id.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -79,16 +80,17 @@
 
   // Called when an account has been added in Chrome from the web (using the
   // DICE protocol).
-  // |web_contents| is the tab where the signin event happened. It must belong
+  // `web_contents` is the tab where the signin event happened. It must belong
   // to the profile associated with this service. It may be nullptr if the tab
   // was closed.
-  // |is_new_account| is true if the account was not already in Chrome (i.e.
+  // `is_new_account` is true if the account was not already in Chrome (i.e.
   // this is not a reauth).
-  // |is_sync_signin| is true if the user is signing in with the intent of
+  // `is_sync_signin` is true if the user is signing in with the intent of
   // enabling sync for that account.
   // Virtual for testing.
   virtual void MaybeInterceptWebSignin(content::WebContents* web_contents,
                                        CoreAccountId account_id,
+                                       signin_metrics::AccessPoint access_point,
                                        bool is_new_account,
                                        bool is_sync_signin);
 
@@ -315,6 +317,8 @@
   base::ScopedObservation<signin::IdentityManager,
                           signin::IdentityManager::Observer>
       account_info_update_observation_{this};
+  signin_metrics::AccessPoint access_point_ =
+      signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN;
 
   // Timeout for waiting for full information to be available (see
   // `ProcessInterceptionOrWait()`).
diff --git a/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc b/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc
index 1a22173..a19dc956 100644
--- a/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc
+++ b/chrome/browser/signin/dice_web_signin_interceptor_browsertest.cc
@@ -44,6 +44,7 @@
 #include "components/password_manager/core/browser/features/password_manager_features_util.h"
 #include "components/prefs/pref_service.h"
 #include "components/signin/public/base/consent_level.h"
+#include "components/signin/public/base/signin_metrics.h"
 #include "components/signin/public/base/signin_switches.h"
 #include "components/signin/public/identity_manager/account_info.h"
 #include "components/signin/public/identity_manager/accounts_mutator.h"
@@ -181,9 +182,11 @@
   DiceWebSigninInterceptor* interceptor =
       DiceWebSigninInterceptorFactory::GetForProfile(
           Profile::FromBrowserContext(contents->GetBrowserContext()));
-  interceptor->MaybeInterceptWebSignin(contents, account_id,
-                                       /*is_new_account=*/true,
-                                       /*is_sync_signin=*/false);
+  interceptor->MaybeInterceptWebSignin(
+      contents, account_id,
+      signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN,
+      /*is_new_account=*/true,
+      /*is_sync_signin=*/false);
   // Wait for the interception to be complete.
   return profile_waiter.WaitForProfileAdded();
 }
@@ -476,9 +479,11 @@
           WebSigninInterceptor::SigninInterceptionType::kProfileSwitch);
   DiceWebSigninInterceptor* interceptor =
       DiceWebSigninInterceptorFactory::GetForProfile(GetProfile());
-  interceptor->MaybeInterceptWebSignin(web_contents, account_info.account_id,
-                                       /*is_new_account=*/true,
-                                       /*is_sync_signin=*/false);
+  interceptor->MaybeInterceptWebSignin(
+      web_contents, account_info.account_id,
+      signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN,
+      /*is_new_account=*/true,
+      /*is_sync_signin=*/false);
 
   // Add the account to the cookies (simulates the account reconcilor).
   signin::SetCookieAccounts(other_identity_manager, test_url_loader_factory(),
@@ -518,9 +523,11 @@
   DiceWebSigninInterceptor* interceptor =
       DiceWebSigninInterceptorFactory::GetForProfile(
           Profile::FromBrowserContext(contents->GetBrowserContext()));
-  interceptor->MaybeInterceptWebSignin(contents, account_info.account_id,
-                                       /*is_new_account=*/true,
-                                       /*is_sync_signin=*/false);
+  interceptor->MaybeInterceptWebSignin(
+      contents, account_info.account_id,
+      signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN,
+      /*is_new_account=*/true,
+      /*is_sync_signin=*/false);
   // Close the source tab during the profile creation.
   contents->Close();
   // Wait for the interception to be complete.
@@ -578,9 +585,11 @@
     DiceWebSigninInterceptor* interceptor =
         DiceWebSigninInterceptorFactory::GetForProfile(
             Profile::FromBrowserContext(contents->GetBrowserContext()));
-    interceptor->MaybeInterceptWebSignin(contents, account_info.account_id,
-                                         /*is_new_account=*/true,
-                                         /*is_sync_signin=*/false);
+    interceptor->MaybeInterceptWebSignin(
+        contents, account_info.account_id,
+        signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN,
+        /*is_new_account=*/true,
+        /*is_sync_signin=*/false);
 
     // Bubble should be shown following the intercept.
     EXPECT_TRUE(interceptor_delegate->intercept_bubble_shown());
@@ -750,6 +759,7 @@
   interceptor->MaybeInterceptWebSignin(
       app_browser->tab_strip_model()->GetActiveWebContents(),
       account_info.account_id,
+      signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN,
       /*is_new_account=*/true,
       /*is_sync_signin=*/false);
 
@@ -888,9 +898,11 @@
   // Start the interception.
   DiceWebSigninInterceptor* interceptor =
       DiceWebSigninInterceptorFactory::GetForProfile(GetProfile());
-  interceptor->MaybeInterceptWebSignin(web_contents, account_info.account_id,
-                                       /*is_new_account=*/true,
-                                       /*is_sync_signin=*/false);
+  interceptor->MaybeInterceptWebSignin(
+      web_contents, account_info.account_id,
+      signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN,
+      /*is_new_account=*/true,
+      /*is_sync_signin=*/false);
   base::RunLoop run_loop;
   run_loop.RunUntilIdle();
 
@@ -1030,9 +1042,11 @@
   // Start the interception.
   DiceWebSigninInterceptor* interceptor =
       DiceWebSigninInterceptorFactory::GetForProfile(GetProfile());
-  interceptor->MaybeInterceptWebSignin(web_contents, account_info.account_id,
-                                       /*is_new_account=*/true,
-                                       /*is_sync_signin=*/false);
+  interceptor->MaybeInterceptWebSignin(
+      web_contents, account_info.account_id,
+      signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN,
+      /*is_new_account=*/true,
+      /*is_sync_signin=*/false);
   base::RunLoop run_loop;
   run_loop.RunUntilIdle();
 
@@ -1089,9 +1103,11 @@
   // Start the interception.
   DiceWebSigninInterceptor* interceptor =
       DiceWebSigninInterceptorFactory::GetForProfile(GetProfile());
-  interceptor->MaybeInterceptWebSignin(web_contents, account_info.account_id,
-                                       /*is_new_account=*/true,
-                                       /*is_sync_signin=*/false);
+  interceptor->MaybeInterceptWebSignin(
+      web_contents, account_info.account_id,
+      signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN,
+      /*is_new_account=*/true,
+      /*is_sync_signin=*/false);
   base::RunLoop run_loop;
   run_loop.RunUntilIdle();
 
@@ -1232,9 +1248,11 @@
   // Start the interception.
   DiceWebSigninInterceptor* interceptor =
       DiceWebSigninInterceptorFactory::GetForProfile(GetProfile());
-  interceptor->MaybeInterceptWebSignin(web_contents, account_info.account_id,
-                                       /*is_new_account=*/false,
-                                       /*is_sync_signin=*/false);
+  interceptor->MaybeInterceptWebSignin(
+      web_contents, account_info.account_id,
+      signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN,
+      /*is_new_account=*/false,
+      /*is_sync_signin=*/false);
   base::RunLoop().RunUntilIdle();
   EXPECT_TRUE(
       chrome::enterprise_util::UserAcceptedAccountManagement(GetProfile()));
@@ -1290,9 +1308,11 @@
   // Start the interception.
   DiceWebSigninInterceptor* interceptor =
       DiceWebSigninInterceptorFactory::GetForProfile(GetProfile());
-  interceptor->MaybeInterceptWebSignin(web_contents, account_info.account_id,
-                                       /*is_new_account=*/false,
-                                       /*is_sync_signin=*/false);
+  interceptor->MaybeInterceptWebSignin(
+      web_contents, account_info.account_id,
+      signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN,
+      /*is_new_account=*/false,
+      /*is_sync_signin=*/false);
   base::RunLoop().RunUntilIdle();
   EXPECT_TRUE(
       chrome::enterprise_util::UserAcceptedAccountManagement(GetProfile()));
@@ -1439,9 +1459,11 @@
           WebSigninInterceptor::SigninInterceptionType::kProfileSwitchForced);
   DiceWebSigninInterceptor* interceptor =
       DiceWebSigninInterceptorFactory::GetForProfile(GetProfile());
-  interceptor->MaybeInterceptWebSignin(web_contents, account_info.account_id,
-                                       /*is_new_account=*/true,
-                                       /*is_sync_signin=*/false);
+  interceptor->MaybeInterceptWebSignin(
+      web_contents, account_info.account_id,
+      signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN,
+      /*is_new_account=*/true,
+      /*is_sync_signin=*/false);
 
   // Add the account to the cookies (simulates the account reconcilor).
   signin::SetCookieAccounts(other_identity_manager, test_url_loader_factory(),
diff --git a/chrome/browser/signin/dice_web_signin_interceptor_unittest.cc b/chrome/browser/signin/dice_web_signin_interceptor_unittest.cc
index 265ac752..3d53728 100644
--- a/chrome/browser/signin/dice_web_signin_interceptor_unittest.cc
+++ b/chrome/browser/signin/dice_web_signin_interceptor_unittest.cc
@@ -22,6 +22,7 @@
 #include "chrome/browser/signin/chrome_signin_client_test_util.h"
 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
 #include "chrome/browser/signin/signin_features.h"
+#include "chrome/browser/signin/web_signin_interceptor.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/pref_names.h"
@@ -32,6 +33,7 @@
 #include "components/policy/core/browser/signin/profile_separation_policies.h"
 #include "components/policy/core/common/management/scoped_management_service_override_for_testing.h"
 #include "components/prefs/pref_service.h"
+#include "components/signin/public/base/signin_metrics.h"
 #include "components/signin/public/base/signin_pref_names.h"
 #include "components/signin/public/base/signin_switches.h"
 #include "components/signin/public/identity_manager/account_capabilities_test_mutator.h"
@@ -163,9 +165,11 @@
   // Helper function that calls MaybeInterceptWebSignin with parameters
   // compatible with interception.
   void MaybeIntercept(CoreAccountId account_id) {
-    interceptor()->MaybeInterceptWebSignin(web_contents(), account_id,
-                                           /*is_new_account=*/true,
-                                           /*is_sync_signin=*/false);
+    interceptor()->MaybeInterceptWebSignin(
+        web_contents(), account_id,
+        signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN,
+        /*is_new_account=*/true,
+        /*is_sync_signin=*/false);
   }
 
   // Calls MaybeInterceptWebSignin and verifies the heuristic outcome, the
@@ -182,9 +186,10 @@
                                                  /*entry=*/nullptr),
               expected_outcome);
     base::HistogramTester histogram_tester;
-    interceptor()->MaybeInterceptWebSignin(web_contents(),
-                                           account_info.account_id,
-                                           is_new_account, is_sync_signin);
+    interceptor()->MaybeInterceptWebSignin(
+        web_contents(), account_info.account_id,
+        signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN, is_new_account,
+        is_sync_signin);
     testing::Mock::VerifyAndClearExpectations(mock_delegate());
     histogram_tester.ExpectUniqueSample("Signin.Intercept.HeuristicOutcome",
                                         expected_outcome, 1);
@@ -209,9 +214,10 @@
                                                  /*entry=*/nullptr),
               absl::nullopt);
     base::HistogramTester histogram_tester;
-    interceptor()->MaybeInterceptWebSignin(web_contents(),
-                                           account_info.account_id,
-                                           is_new_account, is_sync_signin);
+    interceptor()->MaybeInterceptWebSignin(
+        web_contents(), account_info.account_id,
+        signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN, is_new_account,
+        is_sync_signin);
     testing::Mock::VerifyAndClearExpectations(mock_delegate());
     histogram_tester.ExpectUniqueSample("Signin.Intercept.HeuristicOutcome",
                                         expected_outcome, 1);
@@ -1066,6 +1072,7 @@
   base::HistogramTester histogram_tester;
   interceptor()->MaybeInterceptWebSignin(
       /*web_contents=*/nullptr, CoreAccountId(),
+      signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN,
       /*is_new_account=*/true, /*is_sync_signin=*/false);
   histogram_tester.ExpectUniqueSample(
       "Signin.Intercept.HeuristicOutcome",
@@ -1624,7 +1631,67 @@
               ShowSigninInterceptionBubble(
                   web_contents(), MatchBubbleParameters(expected_parameters),
                   testing::_));
-  TestSynchronousInterception(
-      account_info, /*is_new_account=*/true, /*is_sync_signin=*/false,
-      SigninInterceptionHeuristicOutcome::kInterceptChromeSignin);
+
+  auto expected_outcome =
+      SigninInterceptionHeuristicOutcome::kInterceptChromeSignin;
+  base::HistogramTester histogram_tester;
+  interceptor()->MaybeInterceptWebSignin(
+      web_contents(), account_info.account_id,
+      signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN,
+      /*is_new_account=*/true, /*is_sync_signin=*/false);
+  EXPECT_EQ(interceptor()->GetHeuristicOutcome(/*is_new_account=*/true,
+                                               /*is_sync_signin=*/false,
+                                               account_info.email,
+                                               /*entry=*/nullptr),
+            expected_outcome);
+  testing::Mock::VerifyAndClearExpectations(mock_delegate());
+  histogram_tester.ExpectUniqueSample("Signin.Intercept.HeuristicOutcome",
+                                      expected_outcome, 1);
+  histogram_tester.ExpectUniqueTimeSample("Signin.Intercept.HeuristicLatency",
+                                          base::Milliseconds(0), 1);
+
+  EXPECT_EQ(interceptor()->is_interception_in_progress(),
+            SigninInterceptionHeuristicOutcomeIsSuccess(expected_outcome));
+}
+
+TEST_F(DiceWebSigninInterceptorTestWithUnoEnabled,
+       InterceptShouldNotShowChromeSigninBubbleOnAccessPointUnkown) {
+  AccountInfo account_info =
+      identity_test_env()->MakeAccountAvailable("alice@example.com");
+  MakeValidAccountInfo(&account_info);
+  identity_test_env()->UpdateAccountInfoForAccount(account_info);
+
+  // Account is valid.
+  ASSERT_TRUE(account_info.IsValid());
+  // Primary account is not set, Chrome is not signed in.
+  ASSERT_FALSE(identity_test_env()->identity_manager()->HasPrimaryAccount(
+      signin::ConsentLevel::kSignin));
+
+  // Unknown access point is treated as information not complete/compatible and
+  // should not show the bubble even if the rest of the information are valid.
+  auto access_point = signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN;
+  EXPECT_CALL(*mock_delegate(), ShowSigninInterceptionBubble(
+                                    web_contents(), testing::_, testing::_))
+      .Times(0);
+
+  base::HistogramTester histogram_tester;
+  interceptor()->MaybeInterceptWebSignin(
+      web_contents(), account_info.account_id, access_point,
+      /*is_new_account=*/true, /*is_sync_signin=*/false);
+
+  auto expected_outcome =
+      SigninInterceptionHeuristicOutcome::kAbortAccountInfoNotCompatible;
+  EXPECT_EQ(interceptor()->GetHeuristicOutcome(/*is_new_account=*/true,
+                                               /*is_sync_signin=*/false,
+                                               account_info.email,
+                                               /*entry=*/nullptr),
+            absl::nullopt);
+  testing::Mock::VerifyAndClearExpectations(mock_delegate());
+  histogram_tester.ExpectUniqueSample("Signin.Intercept.HeuristicOutcome",
+                                      expected_outcome, 1);
+  histogram_tester.ExpectUniqueTimeSample("Signin.Intercept.HeuristicLatency",
+                                          base::Milliseconds(0), 1);
+
+  EXPECT_EQ(interceptor()->is_interception_in_progress(),
+            SigninInterceptionHeuristicOutcomeIsSuccess(expected_outcome));
 }
diff --git a/chrome/browser/signin/process_dice_header_delegate_impl.cc b/chrome/browser/signin/process_dice_header_delegate_impl.cc
index 87d4938..8821681 100644
--- a/chrome/browser/signin/process_dice_header_delegate_impl.cc
+++ b/chrome/browser/signin/process_dice_header_delegate_impl.cc
@@ -140,8 +140,8 @@
   // sync signin, but it is not always the case: the user may abandon the sync
   // signin and do a simple web signin in the same tab instead.
   DiceWebSigninInterceptorFactory::GetForProfile(&profile_.get())
-      ->MaybeInterceptWebSignin(web_contents_.get(), account_id, is_new_account,
-                                is_sync_signin_tab_);
+      ->MaybeInterceptWebSignin(web_contents_.get(), account_id, access_point_,
+                                is_new_account, is_sync_signin_tab_);
 }
 
 void ProcessDiceHeaderDelegateImpl::EnableSync(
diff --git a/chrome/browser/signin/process_dice_header_delegate_impl_unittest.cc b/chrome/browser/signin/process_dice_header_delegate_impl_unittest.cc
index 9b728d0..00f7789 100644
--- a/chrome/browser/signin/process_dice_header_delegate_impl_unittest.cc
+++ b/chrome/browser/signin/process_dice_header_delegate_impl_unittest.cc
@@ -20,6 +20,7 @@
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "components/signin/public/base/account_consistency_method.h"
+#include "components/signin/public/base/signin_metrics.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "components/signin/public/identity_manager/identity_test_environment.h"
 #include "content/public/browser/web_contents.h"
@@ -77,6 +78,7 @@
               MaybeInterceptWebSignin,
               (content::WebContents * web_contents,
                CoreAccountId account_id,
+               signin_metrics::AccessPoint access_point,
                bool is_new_account,
                bool is_sync_signin),
               (override));
@@ -440,20 +442,30 @@
     ::testing::ValuesIn(kHandleTokenExchangeFailureTestCases));
 
 struct TokenExchangeSuccessConfiguration {
-  bool is_reauth;   // User was already signed in with the account.
-  bool signin_tab;  // A DiceTabHelper is attached to the tab.
-  Reason reason;
-  bool sync_signin;  // Expected value for the MaybeInterceptWebSigin call.
+  bool is_reauth = false;   // User was already signed in with the account.
+  bool signin_tab = false;  // A DiceTabHelper is attached to the tab.
+  Reason reason = Reason::kSigninPrimaryAccount;
+  // Expected value for the MaybeInterceptWebSigin call.
+  bool sync_signin = false;
+  signin_metrics::AccessPoint access_point =
+      signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN;
 };
 
 TokenExchangeSuccessConfiguration kHandleTokenExchangeSuccessTestCases[] = {
     // clang-format off
-    // is_reauth | signin_tab |       reason               | sync_signin
-    {  false,      false,     Reason::kSigninPrimaryAccount, false },
-    {  false,      true,      Reason::kSigninPrimaryAccount, true },
-    {  false,      true,      Reason::kAddSecondaryAccount,  false },
-    {  true,       false,     Reason::kSigninPrimaryAccount, false },
-    {  true,       true,      Reason::kSigninPrimaryAccount, true },
+    // is_reauth | signin_tab |       reason               |
+    //      sync_signin  | access_point
+    {  false,      false,     Reason::kSigninPrimaryAccount,
+            false, signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN },
+    {  false,      true,      Reason::kSigninPrimaryAccount,
+            true, signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE },
+    {  false,      true,      Reason::kAddSecondaryAccount,
+            false, signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE },
+    {  true,       false,     Reason::kSigninPrimaryAccount,
+            false, signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN },
+    {  true,       true,      Reason::kSigninPrimaryAccount,
+            true, signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE },
+
     // clang-format on
 };
 
@@ -473,10 +485,12 @@
       CreateDelegateAndNavigateToSignin(
           GetParam().signin_tab,
           /*redirect_url=*/GURL(chrome::kChromeUINewTabURL), GetParam().reason);
+
   EXPECT_CALL(
       *mock_interceptor(),
       MaybeInterceptWebSignin(web_contents(), account_info_.account_id,
-                              !GetParam().is_reauth, GetParam().sync_signin));
+                              GetParam().access_point, !GetParam().is_reauth,
+                              GetParam().sync_signin));
   delegate->HandleTokenExchangeSuccess(account_info_.account_id,
                                        !GetParam().is_reauth);
 
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 7f36408..cdf2e9d1 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -2124,7 +2124,10 @@
       "webui/family_link_user_internals/family_link_user_internals_ui.cc",
       "webui/family_link_user_internals/family_link_user_internals_ui.h",
     ]
-    deps += [ "//components/supervised_user/core/browser" ]
+    deps += [
+      "//components/supervised_user/core/browser",
+      "//components/supervised_user/core/browser:supervised_user_preferences",
+    ]
   }
 
   if (enable_supervised_users && enable_extensions) {
diff --git a/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view.cc b/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view.cc
index 64e21ed..50dac41 100644
--- a/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view.cc
+++ b/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view.cc
@@ -78,7 +78,7 @@
   for (int i = 0; i < controller_->GetLineCount(); ++i) {
     const Suggestion& suggestion = controller_->GetSuggestionAt(i);
     int android_icon_id = 0;
-    if (!suggestion.icon.empty()) {
+    if (suggestion.icon != Suggestion::Icon::kNoIcon) {
       android_icon_id = ResourceMapper::MapToJavaDrawableId(
           GetIconResourceID(suggestion.icon));
     }
diff --git a/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.cc b/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.cc
index 26818aa..df3f7bc 100644
--- a/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.cc
+++ b/chrome/browser/ui/android/autofill/card_unmask_prompt_view_android.cc
@@ -170,7 +170,7 @@
   return java_object_internal_ = Java_CardUnmaskBridge_create(
              env, reinterpret_cast<intptr_t>(this), dialog_title, instructions,
              ResourceMapper::MapToJavaDrawableId(
-                 GetIconResourceID(controller_->GetCardIconString())),
+                 GetIconResourceID(controller_->GetCardIcon())),
              card_name, card_last_four_digits, card_expiration, card_art_url,
              confirm,
              ResourceMapper::MapToJavaDrawableId(controller_->GetCvcImageRid()),
diff --git a/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerImpl.java b/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerImpl.java
index b776bbbc..c79ab480 100644
--- a/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerImpl.java
+++ b/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerImpl.java
@@ -114,11 +114,7 @@
         }
 
         boolean shouldDrawToEdge = alwaysDrawToEdgeForTabKind(tab);
-        if (!shouldDrawToEdge && tab != null) {
-            shouldDrawToEdge = getWasViewportFitCover(tab);
-            // TODO(https://crbug.com/1499319) Clean up this info-level logging, here and below.
-            Log.i(TAG, "getWasViewportFitCover: %s", shouldDrawToEdge);
-        }
+        if (!shouldDrawToEdge && tab != null) shouldDrawToEdge = getWasViewportFitCover(tab);
         drawToEdge(ROOT_UI_VIEW_ID, shouldDrawToEdge, tab == null ? null : tab.getWebContents());
     }
 
@@ -135,7 +131,6 @@
                 new WebContentsObserver(tab.getWebContents()) {
                     @Override
                     public void viewportFitChanged(@WebContentsObserver.ViewportFitType int value) {
-                        Log.i(TAG, "viewportFitChanged: %s", value);
                         boolean shouldDrawToEdge = alwaysDrawToEdgeForTabKind(tab);
                         if (value == ViewportFit.COVER
                                 || value == ViewportFit.COVER_FORCED_BY_USER_AGENT) {
@@ -158,13 +153,10 @@
     @RequiresApi(VERSION_CODES.R)
     @SuppressWarnings("WrongConstant") // For WindowInsets.Type on U+
     private void drawToEdge(int viewId, boolean toEdge, @Nullable WebContents webContents) {
-        if (toEdge == mIsActivityToEdge) {
-            Log.i(TAG, "drawToEdge unchanged: %s", mIsActivityToEdge);
-            return;
-        }
+        if (toEdge == mIsActivityToEdge) return;
 
         mIsActivityToEdge = toEdge;
-        Log.i(TAG, "Switching %s", (toEdge ? "ToEdge" : "ToNormal"));
+        Log.v(TAG, "Switching %s", (toEdge ? "ToEdge" : "ToNormal"));
         View rootView = mActivity.findViewById(viewId);
         assert rootView != null : "Root view for Edge To Edge not found!";
 
@@ -216,7 +208,6 @@
                 mSystemInsets.top,
                 mSystemInsets.right,
                 bottomInset);
-        Log.i(TAG, "Set bottom padding to %s", bottomInset);
 
         // We only make the Nav Bar transparent because it's the only thing we want to draw
         // underneath.
@@ -241,7 +232,7 @@
         // SafeAreaInsetsTracker.
         assert mSystemInsets != null : "Error, trying to notify Blink without system insets set";
         Rect insetsRect = new Rect(0, 0, 0, toEdge ? scale(mSystemInsets.bottom) : 0);
-        Log.i(TAG, "Pushing back insets to Blink %s", insetsRect);
+        Log.v(TAG, "Pushing back insets to Blink %s", insetsRect);
         webContents.setDisplayCutoutSafeArea(insetsRect);
     }
 
@@ -287,14 +278,6 @@
         assert tab != null;
         SafeAreaInsetsTracker safeAreaInsetsTracker =
                 DisplayCutoutController.getSafeAreaInsetsTracker(tab);
-        // TODO(https://crbug.com/1499319) remove this debug logging.
-        Log.i(
-                TAG,
-                "Tracker for tab '%s' %s",
-                tab.getTitle(),
-                (safeAreaInsetsTracker == null
-                        ? "is null"
-                        : "has cover: " + safeAreaInsetsTracker.isViewportFitCover()));
         return safeAreaInsetsTracker == null ? false : safeAreaInsetsTracker.isViewportFitCover();
     }
 
diff --git a/chrome/browser/ui/android/fast_checkout/internal/BUILD.gn b/chrome/browser/ui/android/fast_checkout/internal/BUILD.gn
index 478f348..31b0ec9 100644
--- a/chrome/browser/ui/android/fast_checkout/internal/BUILD.gn
+++ b/chrome/browser/ui/android/fast_checkout/internal/BUILD.gn
@@ -128,6 +128,7 @@
     "//chrome/browser/ui/android/fast_checkout:java",
     "//chrome/browser/ui/android/fast_checkout/internal:java_resources",
     "//chrome/test/android:chrome_java_test_support_common",
+    "//components/autofill/android:main_autofill_java",
     "//components/browser_ui/bottomsheet/android:java",
     "//third_party/android_deps:espresso_java",
     "//third_party/androidx:androidx_appcompat_appcompat_java",
diff --git a/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutDetailScreenViewTest.java b/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutDetailScreenViewTest.java
index ce4b34b5..cc346546 100644
--- a/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutDetailScreenViewTest.java
+++ b/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutDetailScreenViewTest.java
@@ -54,6 +54,7 @@
 import org.chromium.chrome.browser.ui.fast_checkout.detail_screen.CreditCardItemProperties;
 import org.chromium.chrome.browser.ui.fast_checkout.detail_screen.DetailScreenCoordinator;
 import org.chromium.chrome.browser.ui.fast_checkout.detail_screen.FooterItemProperties;
+import org.chromium.chrome.browser.ui.suggestion.Icon;
 import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.ui.base.TestActivity;
@@ -110,7 +111,7 @@
                     /* obfuscatedNumber= */ "5656",
                     /* month= */ "05",
                     /* year= */ "2031",
-                    /* issuerIconString= */ "visaCC");
+                    /* issuerIcon= */ Icon.CARD_VISA);
 
     private static final FastCheckoutCreditCard sSampleCard2 =
             FastCheckoutTestUtils.createDetailedLocalCreditCard(
@@ -121,7 +122,7 @@
                     /* obfuscatedNumber= */ "1234",
                     /* month= */ "10",
                     /* year= */ "2025",
-                    /* issuerIconString= */ "dinersCC");
+                    /* issuerIcon= */ Icon.CARD_DINERS);
 
     @Before
     public void setUp() {
@@ -277,7 +278,7 @@
                         /* obfuscatedNumber= */ "34326",
                         /* month= */ "05",
                         /* year= */ "2035",
-                        /* issuerIconString= */ "visaCC");
+                        /* issuerIcon= */ Icon.CARD_VISA);
         FastCheckoutCreditCard sampleCardEmptyFields =
                 FastCheckoutTestUtils.createDetailedLocalCreditCard(
                         /* guid= */ "7534",
@@ -287,7 +288,7 @@
                         /* obfuscatedNumber= */ "",
                         /* month= */ "05",
                         /* year= */ "2035",
-                        /* issuerIconString= */ "visaCC");
+                        /* issuerIcon= */ Icon.CARD_VISA);
 
         models.add(
                 new ListItem(
diff --git a/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutHomeScreenViewTest.java b/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutHomeScreenViewTest.java
index 60d6c8d2..fe17509 100644
--- a/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutHomeScreenViewTest.java
+++ b/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutHomeScreenViewTest.java
@@ -38,6 +38,7 @@
 import org.chromium.chrome.browser.ui.fast_checkout.data.FastCheckoutAutofillProfile;
 import org.chromium.chrome.browser.ui.fast_checkout.data.FastCheckoutCreditCard;
 import org.chromium.chrome.browser.ui.fast_checkout.home_screen.HomeScreenCoordinator;
+import org.chromium.chrome.browser.ui.suggestion.Icon;
 import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
 import org.chromium.ui.base.TestActivity;
 import org.chromium.ui.modelutil.PropertyModel;
@@ -80,7 +81,7 @@
                     /* obfuscatedNumber= */ "5656",
                     /* month= */ "05",
                     /* year= */ "2031",
-                    /* issuerIconString= */ "visaCC");
+                    /* issuerIcon= */ Icon.CARD_VISA);
 
     @Before
     public void setUp() {
diff --git a/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutIntegrationTest.java b/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutIntegrationTest.java
index 6314d9c3..405e116 100644
--- a/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutIntegrationTest.java
+++ b/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutIntegrationTest.java
@@ -40,6 +40,7 @@
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.ui.fast_checkout.data.FastCheckoutAutofillProfile;
 import org.chromium.chrome.browser.ui.fast_checkout.data.FastCheckoutCreditCard;
+import org.chromium.chrome.browser.ui.suggestion.Icon;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetContent;
@@ -92,7 +93,7 @@
                 /* obfuscatedNumber= */ "1111",
                 /* month= */ "11",
                 /* year= */ "2023",
-                /* issuerIconString= */ "dinersCC"),
+                /* issuerIcon= */ Icon.CARD_DINERS),
         FastCheckoutTestUtils.createDetailedLocalCreditCard(
                 /* guid= */ "431",
                 /* origin= */ "https://example.fr",
@@ -101,7 +102,7 @@
                 /* obfuscatedNumber= */ "1234",
                 /* month= */ "10",
                 /* year= */ "2025",
-                /* issuerIconString= */ "visaCC")
+                /* issuerIcon= */ Icon.CARD_VISA)
     };
 
     private FastCheckoutComponent mFastCheckout;
diff --git a/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutRenderTest.java b/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutRenderTest.java
index 42848ac..8712e72 100644
--- a/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutRenderTest.java
+++ b/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutRenderTest.java
@@ -38,6 +38,7 @@
 import org.chromium.chrome.browser.night_mode.ChromeNightModeTestUtils;
 import org.chromium.chrome.browser.ui.fast_checkout.data.FastCheckoutAutofillProfile;
 import org.chromium.chrome.browser.ui.fast_checkout.data.FastCheckoutCreditCard;
+import org.chromium.chrome.browser.ui.suggestion.Icon;
 import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
 import org.chromium.chrome.test.util.ChromeRenderTestRule;
@@ -77,7 +78,7 @@
                     /* obfuscatedNumber= */ "• • • • 5656",
                     /* month= */ "05",
                     /* year= */ AutofillTestHelper.nextYear(),
-                    /* issuerIconString= */ "visaCC");
+                    /* issuerIcon= */ Icon.CARD_VISA);
     private static final FastCheckoutCreditCard SERVER_CREDIT_CARD =
             FastCheckoutTestUtils.createDetailedCreditCard(
                     /* guid= */ "123",
@@ -88,7 +89,7 @@
                     /* obfuscatedNumber= */ "• • • • 5656",
                     /* month= */ "05",
                     /* year= */ AutofillTestHelper.nextYear(),
-                    /* issuerIconString= */ "visaCC");
+                    /* issuerIcon= */ Icon.CARD_VISA);
 
     @ParameterAnnotations.ClassParameter
     private static List<ParameterSet> sClassParams =
diff --git a/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutTestUtils.java b/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutTestUtils.java
index 4e8e2d3..caa4f4d 100644
--- a/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutTestUtils.java
+++ b/chrome/browser/ui/android/fast_checkout/internal/junit/src/org/chromium/chrome/browser/ui/fast_checkout/FastCheckoutTestUtils.java
@@ -6,6 +6,7 @@
 
 import org.chromium.chrome.browser.ui.fast_checkout.data.FastCheckoutAutofillProfile;
 import org.chromium.chrome.browser.ui.fast_checkout.data.FastCheckoutCreditCard;
+import org.chromium.chrome.browser.ui.suggestion.Icon;
 import org.chromium.components.autofill.VirtualCardEnrollmentState;
 
 /** A collection of helper methods for FastCheckout tests. */
@@ -29,32 +30,70 @@
                 /*postalCode=*/"", email, /*phoneNumber=*/"");
     }
 
-    /** Creates a detailed {@link FastCheckoutCreditCard}.  */
-    static FastCheckoutCreditCard createDetailedCreditCard(String guid, String origin,
-            boolean isLocal, String name, String number, String obfuscatedNumber, String month,
-            String year, String issuerIconString) {
-        return new FastCheckoutCreditCard(guid, origin, /* isLocal= */ isLocal,
-                /* isCached= */ true, name, number, obfuscatedNumber, month, year,
-                /* basicCardIssuerNetwork= */ "visa", issuerIconString,
+    /** Creates a detailed {@link FastCheckoutCreditCard}. */
+    static FastCheckoutCreditCard createDetailedCreditCard(
+            String guid,
+            String origin,
+            boolean isLocal,
+            String name,
+            String number,
+            String obfuscatedNumber,
+            String month,
+            String year,
+            @Icon int issuerIcon) {
+        return new FastCheckoutCreditCard(
+                guid,
+                origin,
+                /* isLocal= */ isLocal,
+                /* isCached= */ true,
+                name,
+                number,
+                obfuscatedNumber,
+                month,
+                year,
+                /* basicCardIssuerNetwork= */ "visa",
+                issuerIcon,
                 /* billingAddressId= */ "john",
-                /* serverId= */ "", /* instrumentId= */ 0, /* nickname= */ "",
+                /* serverId= */ "",
+                /* instrumentId= */ 0,
+                /* nickname= */ "",
                 /* cardArtUrl= */ null,
                 /* virtualCardEnrollmentState= */ VirtualCardEnrollmentState.UNSPECIFIED,
                 /* productDescription= */ "");
     }
 
-    /** Creates a detailed local {@link FastCheckoutCreditCard}.  */
-    static FastCheckoutCreditCard createDetailedLocalCreditCard(String guid, String origin,
-            String name, String number, String obfuscatedNumber, String month, String year,
-            String issuerIconString) {
-        return createDetailedCreditCard(guid, origin, /* isLocal= */ true, name, number,
-                obfuscatedNumber, month, year, issuerIconString);
+    /** Creates a detailed local {@link FastCheckoutCreditCard}. */
+    static FastCheckoutCreditCard createDetailedLocalCreditCard(
+            String guid,
+            String origin,
+            String name,
+            String number,
+            String obfuscatedNumber,
+            String month,
+            String year,
+            @Icon int issuerIcon) {
+        return createDetailedCreditCard(
+                guid,
+                origin,
+                /* isLocal= */ true,
+                name,
+                number,
+                obfuscatedNumber,
+                month,
+                year,
+                issuerIcon);
     }
 
     /** Creates a simple {@link FastCheckoutCreditCard}.  */
     static FastCheckoutCreditCard createDummyCreditCard(String guid, String origin, String number) {
-        return createDetailedLocalCreditCard(guid, origin, /* name= */ "John Doe", number,
-                /* obfuscatedNumber= */ "1111", /* month= */ "12", /* year= */ "2050",
-                /* issuerIconString= */ "visaCC");
+        return createDetailedLocalCreditCard(
+                guid,
+                origin,
+                /* name= */ "John Doe",
+                number,
+                /* obfuscatedNumber= */ "1111",
+                /* month= */ "12",
+                /* year= */ "2050",
+                /* issuerIcon= */ Icon.CARD_VISA);
     }
 }
diff --git a/chrome/browser/ui/android/fast_checkout/java/src/org/chromium/chrome/browser/ui/fast_checkout/data/FastCheckoutCreditCard.java b/chrome/browser/ui/android/fast_checkout/java/src/org/chromium/chrome/browser/ui/fast_checkout/data/FastCheckoutCreditCard.java
index ff61dbc..ec1040a 100644
--- a/chrome/browser/ui/android/fast_checkout/java/src/org/chromium/chrome/browser/ui/fast_checkout/data/FastCheckoutCreditCard.java
+++ b/chrome/browser/ui/android/fast_checkout/java/src/org/chromium/chrome/browser/ui/fast_checkout/data/FastCheckoutCreditCard.java
@@ -11,6 +11,7 @@
 
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.ui.fast_checkout.R;
+import org.chromium.chrome.browser.ui.suggestion.Icon;
 import org.chromium.components.autofill.VirtualCardEnrollmentState;
 import org.chromium.url.GURL;
 
@@ -22,37 +23,38 @@
 public class FastCheckoutCreditCard {
     // Mappings from name: chrome/browser/ui/autofill/autofill_popup_controller_utils.cc
     // Mappings to resource: chrome/browser/android/resource_id.h
-    private static final Map<String, Integer> sResourceMap;
-    private static final Map<String, Integer> sResourceMetadataMap;
+    private static final Map<Integer, Integer> sResourceMap;
+    private static final Map<Integer, Integer> sResourceMetadataMap;
+
     static {
-        Map<String, Integer> map = new ArrayMap<>();
-        Map<String, Integer> metadataMap = new ArrayMap<>();
+        Map<Integer, Integer> map = new ArrayMap<>();
+        Map<Integer, Integer> metadataMap = new ArrayMap<>();
 
-        map.put("americanExpressCC", R.drawable.amex_card);
-        map.put("dinersCC", R.drawable.diners_card);
-        map.put("discoverCC", R.drawable.discover_card);
-        map.put("eloCC", R.drawable.elo_card);
-        map.put("genericCC", R.drawable.ic_credit_card_black);
-        map.put("jcbCC", R.drawable.jcb_card);
-        map.put("masterCardCC", R.drawable.mc_card);
-        map.put("mirCC", R.drawable.mir_card);
-        map.put("troyCC", R.drawable.troy_card);
-        map.put("unionPayCC", R.drawable.unionpay_card);
-        map.put("visaCC", R.drawable.visa_card);
-        map.put("googlePay", R.drawable.google_pay);
+        map.put(Icon.CARD_AMERICAN_EXPRESS, R.drawable.amex_card);
+        map.put(Icon.CARD_DINERS, R.drawable.diners_card);
+        map.put(Icon.CARD_DISCOVER, R.drawable.discover_card);
+        map.put(Icon.CARD_ELO, R.drawable.elo_card);
+        map.put(Icon.CARD_GENERIC, R.drawable.ic_credit_card_black);
+        map.put(Icon.CARD_JCB, R.drawable.jcb_card);
+        map.put(Icon.CARD_MASTER_CARD, R.drawable.mc_card);
+        map.put(Icon.CARD_MIR, R.drawable.mir_card);
+        map.put(Icon.CARD_TROY, R.drawable.troy_card);
+        map.put(Icon.CARD_UNION_PAY, R.drawable.unionpay_card);
+        map.put(Icon.CARD_VISA, R.drawable.visa_card);
+        map.put(Icon.GOOGLE_PAY, R.drawable.google_pay);
 
-        metadataMap.put("americanExpressCC", R.drawable.amex_metadata_card);
-        metadataMap.put("dinersCC", R.drawable.diners_metadata_card);
-        metadataMap.put("discoverCC", R.drawable.discover_metadata_card);
-        metadataMap.put("eloCC", R.drawable.elo_metadata_card);
-        metadataMap.put("genericCC", R.drawable.ic_metadata_credit_card);
-        metadataMap.put("jcbCC", R.drawable.jcb_metadata_card);
-        metadataMap.put("masterCardCC", R.drawable.mc_metadata_card);
-        metadataMap.put("mirCC", R.drawable.mir_metadata_card);
-        metadataMap.put("troyCC", R.drawable.troy_metadata_card);
-        metadataMap.put("unionPayCC", R.drawable.unionpay_metadata_card);
-        metadataMap.put("visaCC", R.drawable.visa_metadata_card);
-        metadataMap.put("googlePay", R.drawable.google_pay);
+        metadataMap.put(Icon.CARD_AMERICAN_EXPRESS, R.drawable.amex_metadata_card);
+        metadataMap.put(Icon.CARD_DINERS, R.drawable.diners_metadata_card);
+        metadataMap.put(Icon.CARD_DISCOVER, R.drawable.discover_metadata_card);
+        metadataMap.put(Icon.CARD_ELO, R.drawable.elo_metadata_card);
+        metadataMap.put(Icon.CARD_GENERIC, R.drawable.ic_metadata_credit_card);
+        metadataMap.put(Icon.CARD_JCB, R.drawable.jcb_metadata_card);
+        metadataMap.put(Icon.CARD_MASTER_CARD, R.drawable.mc_metadata_card);
+        metadataMap.put(Icon.CARD_MIR, R.drawable.mir_metadata_card);
+        metadataMap.put(Icon.CARD_TROY, R.drawable.troy_metadata_card);
+        metadataMap.put(Icon.CARD_UNION_PAY, R.drawable.unionpay_metadata_card);
+        metadataMap.put(Icon.CARD_VISA, R.drawable.visa_metadata_card);
+        metadataMap.put(Icon.GOOGLE_PAY, R.drawable.google_pay);
 
         sResourceMap = map;
         sResourceMetadataMap = metadataMap;
@@ -67,7 +69,7 @@
     private final String mMonth;
     private final String mYear;
     private final String mBasicCardIssuerNetwork;
-    private final String mIssuerIconString;
+    private final @Icon int mIssuerIcon;
     private final String mBillingAddressId;
     private final String mServerId;
     private final long mInstrumentId;
@@ -77,11 +79,25 @@
     private final String mProductDescription;
 
     @CalledByNative
-    public FastCheckoutCreditCard(String guid, String origin, boolean isLocal, boolean isCached,
-            String name, String number, String obfuscatedNumber, String month, String year,
-            String basicCardIssuerNetwork, String issuerIconString, String billingAddressId,
-            String serverId, long instrumentId, String nickname, GURL cardArtUrl,
-            @VirtualCardEnrollmentState int virtualCardEnrollmentState, String productDescription) {
+    public FastCheckoutCreditCard(
+            String guid,
+            String origin,
+            boolean isLocal,
+            boolean isCached,
+            String name,
+            String number,
+            String obfuscatedNumber,
+            String month,
+            String year,
+            String basicCardIssuerNetwork,
+            @Icon int issuerIcon,
+            String billingAddressId,
+            String serverId,
+            long instrumentId,
+            String nickname,
+            GURL cardArtUrl,
+            @VirtualCardEnrollmentState int virtualCardEnrollmentState,
+            String productDescription) {
         mGUID = guid;
         mOrigin = origin;
         mIsLocal = isLocal;
@@ -92,7 +108,7 @@
         mMonth = month;
         mYear = year;
         mBasicCardIssuerNetwork = basicCardIssuerNetwork;
-        mIssuerIconString = issuerIconString;
+        mIssuerIcon = issuerIcon;
         mBillingAddressId = billingAddressId;
         mServerId = serverId;
         mInstrumentId = instrumentId;
@@ -151,8 +167,8 @@
         return mBasicCardIssuerNetwork;
     }
 
-    public String getIssuerIconString() {
-        return mIssuerIconString;
+    public @Icon int getIssuerIcon() {
+        return mIssuerIcon;
     }
 
     @CalledByNative
@@ -197,7 +213,7 @@
     }
 
     public int getIssuerIconDrawableId() {
-        String issuerIconDrawable = getIssuerIconString();
+        @Icon int issuerIconDrawable = getIssuerIcon();
         if (ChromeFeatureList.isEnabled(
                     ChromeFeatureList.AUTOFILL_ENABLE_NEW_CARD_ART_AND_NETWORK_IMAGES)) {
             if (sResourceMetadataMap.containsKey(issuerIconDrawable)) {
diff --git a/chrome/browser/ui/android/fast_checkout/ui_view_android_utils.cc b/chrome/browser/ui/android/fast_checkout/ui_view_android_utils.cc
index dff12002..31f9014 100644
--- a/chrome/browser/ui/android/fast_checkout/ui_view_android_utils.cc
+++ b/chrome/browser/ui/android/fast_checkout/ui_view_android_utils.cc
@@ -99,8 +99,7 @@
           env, credit_card.GetRawInfo(autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR)),
       ConvertUTF8ToJavaString(env,
                               payment_request_data.basic_card_issuer_network),
-      ConvertUTF8ToJavaString(
-          env, credit_card.CardIconStringForAutofillSuggestion()),
+      static_cast<jint>(credit_card.CardIconStringForAutofillSuggestion()),
       ConvertUTF8ToJavaString(env, credit_card.billing_address_id()),
       ConvertUTF8ToJavaString(env, credit_card.server_id()),
       credit_card.instrument_id(),
diff --git a/chrome/browser/ui/app_icon_loader_delegate.h b/chrome/browser/ui/app_icon_loader_delegate.h
index 0d0c8cc4..4c4bc76 100644
--- a/chrome/browser/ui/app_icon_loader_delegate.h
+++ b/chrome/browser/ui/app_icon_loader_delegate.h
@@ -19,9 +19,13 @@
   // 'image' is the main app image, `badge_image` if set is the badge that
   // should be painted on top of the main image for certain app types
   // (currently, `badge_image` will be set for app shortcuts).
+  // 'is_placeholder_icon' is true if the main app image is a placeholder icon.
+  // A promise app may have a placeholder icon while the IconLoader finishes
+  // resolving the resource or is unable to fetch one.
   virtual void OnAppImageUpdated(
       const std::string& app_id,
       const gfx::ImageSkia& image,
+      bool is_placeholder_icon,
       const absl::optional<gfx::ImageSkia>& badge_image) = 0;
 
  protected:
diff --git a/chrome/browser/ui/ash/shelf/arc_app_window.cc b/chrome/browser/ui/ash/shelf/arc_app_window.cc
index 65d3dbe9..38cfdc4 100644
--- a/chrome/browser/ui/ash/shelf/arc_app_window.cc
+++ b/chrome/browser/ui/ash/shelf/arc_app_window.cc
@@ -89,6 +89,7 @@
 void ArcAppWindow::OnAppImageUpdated(
     const std::string& app_id,
     const gfx::ImageSkia& image,
+    bool is_placeholder_icon,
     const absl::optional<gfx::ImageSkia>& badge_image) {
   if (image_fetching_) {
     // This is default app icon. Don't assign it right now to avoid flickering.
diff --git a/chrome/browser/ui/ash/shelf/arc_app_window.h b/chrome/browser/ui/ash/shelf/arc_app_window.h
index 6f725ee..6a1224b 100644
--- a/chrome/browser/ui/ash/shelf/arc_app_window.h
+++ b/chrome/browser/ui/ash/shelf/arc_app_window.h
@@ -61,6 +61,7 @@
   void OnAppImageUpdated(
       const std::string& app_id,
       const gfx::ImageSkia& image,
+      bool is_placeholder_icon,
       const absl::optional<gfx::ImageSkia>& badge_image) override;
 
  private:
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc
index 653ed65e..7f4c77e 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc
@@ -1192,6 +1192,7 @@
 void ChromeShelfController::OnAppImageUpdated(
     const std::string& app_id,
     const gfx::ImageSkia& image,
+    bool is_placeholder_icon,
     const absl::optional<gfx::ImageSkia>& badge_image) {
   TRACE_EVENT0("ui", "ChromeShelfController::OnAppImageUpdated");
   bool is_standard_icon = true;
@@ -1204,7 +1205,7 @@
   }
 
   if (is_standard_icon) {
-    UpdateAppImage(app_id, badge_image, image);
+    UpdateAppImage(app_id, badge_image, is_placeholder_icon, image);
     return;
   }
 
@@ -1225,12 +1226,14 @@
   standard_icon_task_runner_->PostTaskAndReplyWithResult(
       FROM_HERE, base::BindOnce(&CreateStandardImageOnWorkerThread, copy),
       base::BindOnce(&ChromeShelfController::UpdateAppImage,
-                     weak_ptr_factory_.GetWeakPtr(), app_id, badge_image));
+                     weak_ptr_factory_.GetWeakPtr(), app_id, badge_image,
+                     is_placeholder_icon));
 }
 
 void ChromeShelfController::UpdateAppImage(
     const std::string& app_id,
     const absl::optional<gfx::ImageSkia>& badge_image,
+    bool is_placeholder_icon,
     const gfx::ImageSkia& image) {
   TRACE_EVENT0("ui", "ChromeShelfController::UpdateAppImage");
   // TODO: need to get this working for shortcuts.
@@ -1243,6 +1246,7 @@
     }
     item.image = image;
     item.badge_image = badge_image.value_or(gfx::ImageSkia());
+    item.has_placeholder_icon = is_placeholder_icon;
     shelf_spinner_controller_->MaybeApplySpinningEffect(app_id, &item.image);
     item.notification_badge_color =
         ash::AppIconColorCache::GetInstance().GetLightVibrantColorForApp(app_id,
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller.h b/chrome/browser/ui/ash/shelf/chrome_shelf_controller.h
index 0cdf157..085b9ca 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller.h
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller.h
@@ -289,6 +289,7 @@
   void OnAppImageUpdated(
       const std::string& app_id,
       const gfx::ImageSkia& image,
+      bool is_placeholder_icon,
       const absl::optional<gfx::ImageSkia>& badge_image) override;
 
   // Inserts a shelf item for an app at |index|. Note that |index| may be
@@ -313,6 +314,7 @@
   // Updates images of shelf items representing the app.
   void UpdateAppImage(const std::string& app_id,
                       const absl::optional<gfx::ImageSkia>& badge_image,
+                      bool is_placeholder_icon,
                       const gfx::ImageSkia& image);
 
   // Remembers / restores list of running applications.
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 f8d71e3f..1f4544b 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
@@ -143,6 +143,7 @@
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/pref_names.h"
+#include "chrome/grit/branded_strings.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "chrome/test/base/test_browser_window_aura.h"
 #include "chrome/test/base/testing_profile.h"
@@ -196,6 +197,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/aura/client/window_parenting_client.h"
 #include "ui/aura/window.h"
+#include "ui/base/l10n/l10n_util.h"
 #include "ui/base/models/menu_model.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/base/ui_base_features.h"
@@ -1946,7 +1948,8 @@
 
 TEST_F(ChromeShelfControllerLacrosTest, LacrosPinnedByDefault) {
   InitShelfController();
-  EXPECT_EQ("Chrome", GetPinnedAppStatus());
+  std::string lacros_app_name = l10n_util::GetStringUTF8(IDS_PRODUCT_NAME);
+  EXPECT_EQ(lacros_app_name, GetPinnedAppStatus());
 }
 
 // Checks that AppService instance is updated appropriately for one Chrome app
diff --git a/chrome/browser/ui/ash/shelf/crostini_app_window.cc b/chrome/browser/ui/ash/shelf/crostini_app_window.cc
index 85df1d0a..62ed8b17 100644
--- a/chrome/browser/ui/ash/shelf/crostini_app_window.cc
+++ b/chrome/browser/ui/ash/shelf/crostini_app_window.cc
@@ -41,6 +41,7 @@
   void OnAppImageUpdated(
       const std::string& app_id,
       const gfx::ImageSkia& image,
+      bool is_placeholder_icon,
       const absl::optional<gfx::ImageSkia>& badge_image) override {
     if (!widget_ || !widget_->widget_delegate())
       return;
diff --git a/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter_unittest.cc b/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter_unittest.cc
index d1442ea..01cc1278 100644
--- a/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter_unittest.cc
+++ b/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter_unittest.cc
@@ -58,7 +58,8 @@
 Suggestion createPasswordEntry(std::string password,
                                std::string username,
                                std::string psl_origin) {
-  Suggestion s(/*main_text=*/username, /*label=*/psl_origin, /*icon=*/"",
+  Suggestion s(/*main_text=*/username, /*label=*/psl_origin,
+               /*icon=*/Suggestion::Icon::kNoIcon,
                PopupItemId::kAutocompleteEntry);
   s.additional_label = ASCIIToUTF16(password);
   return s;
@@ -74,8 +75,8 @@
 
 std::vector<Suggestion> createSuggestions(int clearItemOffset) {
   std::vector<Suggestion> suggestions = createSuggestions();
-  suggestions.emplace(suggestions.begin() + clearItemOffset, "Clear", "", "",
-                      PopupItemId::kClearForm);
+  suggestions.emplace(suggestions.begin() + clearItemOffset, "Clear", "",
+                      Suggestion::Icon::kNoIcon, PopupItemId::kClearForm);
   return suggestions;
 }
 
@@ -101,20 +102,23 @@
 // Matcher returning true if suggestions have equal members.
 MATCHER_P(equalsSuggestion, other, "") {
   if (arg.popup_item_id != other.popup_item_id) {
-    *result_listener << "has popup_item_id "
-                     << base::to_underlying(arg.popup_item_id);
+    *result_listener << "has a different popup_item_id:\n"
+                     << ::testing::PrintToString(arg) << "\n";
     return false;
   }
   if (arg.main_text != other.main_text) {
-    *result_listener << "has main_text " << arg.main_text.value;
+    *result_listener << "has a different main_text:\n"
+                     << ::testing::PrintToString(arg) << "\n";
     return false;
   }
   if (arg.labels != other.labels) {
-    *result_listener << "has labels " << SuggestionLabelsToString(arg.labels);
+    *result_listener << "has different labels:\n"
+                     << SuggestionLabelsToString(arg.labels) << "\n";
     return false;
   }
   if (arg.icon != other.icon) {
-    *result_listener << "has icon " << arg.icon;
+    *result_listener << "has a different icon:\n"
+                     << ::testing::PrintToString(arg) << "\n";
     return false;
   }
   return true;
diff --git a/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller_unittest.mm b/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller_unittest.mm
index 3290ed91..2609fcb 100644
--- a/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller_unittest.mm
@@ -52,7 +52,8 @@
     std::vector<Suggestion> suggestions;
     suggestions.reserve(popup_item_ids.size());
     for (autofill::PopupItemId popup_item_id : popup_item_ids) {
-      suggestions.emplace_back("", "", "", popup_item_id);
+      suggestions.emplace_back("", "", Suggestion::Icon::kNoIcon,
+                               popup_item_id);
     }
     SetSuggestions(std::move(suggestions));
   }
@@ -106,8 +107,9 @@
 // Tests for for the credit card button.
 TEST_F(CreditCardAutofillTouchBarControllerUnitTest, CreditCardButtonCheck) {
   [touch_bar_controller_ setIsCreditCardPopup:true];
-  SetSuggestions({Suggestion("bufflehead", "canvasback", "goldeneye",
-                             PopupItemId::kCreditCardEntry)});
+  SetSuggestions(
+      {Suggestion("bufflehead", "canvasback", Suggestion::Icon::kNoIcon,
+                  PopupItemId::kCreditCardEntry)});
   NSButton* button = [touch_bar_controller_ createCreditCardButtonAtRow:0];
   EXPECT_TRUE(button);
   EXPECT_EQ(0, [button tag]);
diff --git a/chrome/browser/ui/managed_ui.cc b/chrome/browser/ui/managed_ui.cc
index ab702ad..aaa6915 100644
--- a/chrome/browser/ui/managed_ui.cc
+++ b/chrome/browser/ui/managed_ui.cc
@@ -28,6 +28,7 @@
 #include "components/policy/proto/device_management_backend.pb.h"
 #include "components/signin/public/identity_manager/account_info.h"
 #include "components/strings/grit/components_strings.h"
+#include "components/supervised_user/core/browser/supervised_user_preferences.h"
 #include "components/supervised_user/core/common/buildflags.h"
 #include "components/vector_icons/vector_icons.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -107,11 +108,7 @@
   // * on ChromeOS, because similar UI is displayed at the OS level.
   return false;
 #else
-
-  const auto* const supervised_user_service =
-      SupervisedUserServiceFactory::GetForProfile(profile);
-  return supervised_user_service &&
-         supervised_user_service->IsSubjectToParentalControls() &&
+  return profile && supervised_user::IsChildAccount(*profile->GetPrefs()) &&
          base::FeatureList::IsEnabled(
              supervised_user::kEnableManagedByParentUi);
 #endif  // !BUILDFLAG(ENABLE_SUPERVISED_USERS) || BUILDFLAG(IS_CHROMEOS)
diff --git a/chrome/browser/ui/side_panel/side_panel_enums.h b/chrome/browser/ui/side_panel/side_panel_enums.h
index 0d0f4425..9666827 100644
--- a/chrome/browser/ui/side_panel/side_panel_enums.h
+++ b/chrome/browser/ui/side_panel/side_panel_enums.h
@@ -11,6 +11,7 @@
 // here.
 enum class SidePanelOpenTrigger {
   kToolbarButton = 0,
+  kMinValue = kToolbarButton,
   kLensContextMenu = 1,
   kSideSearchPageAction = 2,
   kNotesInPageContextMenu = 3,
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc
index 4d48f5d..63719d2 100644
--- a/chrome/browser/ui/toolbar/app_menu_model.cc
+++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -1141,6 +1141,20 @@
       }
       LogMenuAction(MENU_ACTION_SHOW_CHROME_LABS);
       break;
+    case IDC_SHOW_HISTORY_CLUSTERS_SIDE_PANEL:
+      if (!uma_action_recorded_) {
+        UMA_HISTOGRAM_MEDIUM_TIMES(
+            "WrenchMenu.TimeToAction.ShowHistoryClustersSidePanel", delta);
+      }
+      LogMenuAction(MENU_ACTION_SHOW_HISTORY_CLUSTER_SIDE_PANEL);
+      break;
+    case IDC_SHOW_READING_MODE_SIDE_PANEL:
+      if (!uma_action_recorded_) {
+        UMA_HISTOGRAM_MEDIUM_TIMES(
+            "WrenchMenu.TimeToAction.ShowReadingModeSidePanel", delta);
+      }
+      LogMenuAction(MENU_ACTION_SHOW_READING_MODE_SIDE_PANEL);
+      break;
 
     // Zoom menu
     case IDC_ZOOM_MINUS:
diff --git a/chrome/browser/ui/toolbar/app_menu_model.h b/chrome/browser/ui/toolbar/app_menu_model.h
index 615a36a..e1ea665b 100644
--- a/chrome/browser/ui/toolbar/app_menu_model.h
+++ b/chrome/browser/ui/toolbar/app_menu_model.h
@@ -103,6 +103,8 @@
   MENU_ACTION_SHOW_SEARCH_COMPANION = 81,
   MENU_ACTION_SHOW_BOOKMARK_SIDE_PANEL = 82,
   MENU_ACTION_SHOW_PERFORMANCE_SETTINGS = 83,
+  MENU_ACTION_SHOW_HISTORY_CLUSTER_SIDE_PANEL = 84,
+  MENU_ACTION_SHOW_READING_MODE_SIDE_PANEL = 85,
 
   LIMIT_MENU_ACTION
 };
diff --git a/chrome/browser/ui/views/arc_app_dialog_view.cc b/chrome/browser/ui/views/arc_app_dialog_view.cc
index d526d7b..cd48ea6 100644
--- a/chrome/browser/ui/views/arc_app_dialog_view.cc
+++ b/chrome/browser/ui/views/arc_app_dialog_view.cc
@@ -64,6 +64,7 @@
   void OnAppImageUpdated(
       const std::string& app_id,
       const gfx::ImageSkia& image,
+      bool is_placeholder_icon,
       const absl::optional<gfx::ImageSkia>& badge_image) override;
 
   void AddMultiLineLabel(views::View* parent, const std::u16string& label_text);
@@ -184,6 +185,7 @@
 void ArcAppDialogView::OnAppImageUpdated(
     const std::string& app_id,
     const gfx::ImageSkia& image,
+    bool is_placeholder_icon,
     const absl::optional<gfx::ImageSkia>& badge_image) {
   DCHECK_EQ(app_id, app_id_);
   DCHECK(!image.isNull());
diff --git a/chrome/browser/ui/views/arc_data_removal_dialog_view.cc b/chrome/browser/ui/views/arc_data_removal_dialog_view.cc
index cf70aca..59235ca 100644
--- a/chrome/browser/ui/views/arc_data_removal_dialog_view.cc
+++ b/chrome/browser/ui/views/arc_data_removal_dialog_view.cc
@@ -55,6 +55,7 @@
   void OnAppImageUpdated(
       const std::string& app_id,
       const gfx::ImageSkia& image,
+      bool is_placeholder_icon,
       const absl::optional<gfx::ImageSkia>& badge_image) override;
 
   // ArcSessionManagerObserver:
@@ -135,6 +136,7 @@
 void DataRemovalConfirmationDialog::OnAppImageUpdated(
     const std::string& app_id,
     const gfx::ImageSkia& image,
+    bool is_placeholder_icon,
     const absl::optional<gfx::ImageSkia>& badge_image) {
   DCHECK(!image.isNull());
   DCHECK_EQ(image.width(), kArcAppIconSize);
diff --git a/chrome/browser/ui/views/autofill/popup/popup_cell_utils.cc b/chrome/browser/ui/views/autofill/popup/popup_cell_utils.cc
index 497a97d4..22a7fbc 100644
--- a/chrome/browser/ui/views/autofill/popup/popup_cell_utils.cc
+++ b/chrome/browser/ui/views/autofill/popup/popup_cell_utils.cc
@@ -72,40 +72,40 @@
 
 // Returns the name of the network for payment method icons, empty string
 // otherwise.
-std::u16string GetIconAccessibleName(const std::string& icon_text) {
+std::u16string GetIconAccessibleName(Suggestion::Icon icon) {
   // Networks for which icons are currently shown.
-  if (icon_text == autofill::kAmericanExpressCard) {
+  if (icon == Suggestion::Icon::kCardAmericanExpress) {
     return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_AMEX);
   }
-  if (icon_text == autofill::kDinersCard) {
+  if (icon == Suggestion::Icon::kCardDiners) {
     return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_DINERS);
   }
-  if (icon_text == autofill::kDiscoverCard) {
+  if (icon == Suggestion::Icon::kCardDiscover) {
     return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_DISCOVER);
   }
-  if (icon_text == autofill::kEloCard) {
+  if (icon == Suggestion::Icon::kCardElo) {
     return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_ELO);
   }
-  if (icon_text == autofill::kJCBCard) {
+  if (icon == Suggestion::Icon::kCardJCB) {
     return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_JCB);
   }
-  if (icon_text == autofill::kMasterCard) {
+  if (icon == Suggestion::Icon::kCardMasterCard) {
     return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_MASTERCARD);
   }
-  if (icon_text == autofill::kMirCard) {
+  if (icon == Suggestion::Icon::kCardMir) {
     return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_MIR);
   }
-  if (icon_text == autofill::kTroyCard) {
+  if (icon == Suggestion::Icon::kCardTroy) {
     return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_TROY);
   }
-  if (icon_text == autofill::kUnionPay) {
+  if (icon == Suggestion::Icon::kCardUnionPay) {
     return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_UNION_PAY);
   }
-  if (icon_text == autofill::kVisaCard) {
+  if (icon == Suggestion::Icon::kCardVisa) {
     return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_VISA);
   }
   // Other networks.
-  if (icon_text == autofill::kGenericCard) {
+  if (icon == Suggestion::Icon::kCardGeneric) {
     return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_GENERIC);
   }
   return std::u16string();
@@ -122,76 +122,76 @@
 }
 
 std::unique_ptr<views::ImageView> GetIconImageViewByName(
-    const std::string& icon_str) {
-  if (icon_str.empty()) {
+    Suggestion::Icon icon) {
+  if (icon == Suggestion::Icon::kNoIcon) {
     return nullptr;
   }
 
   // For http warning message, get icon images from VectorIcon, which is the
   // same as security indicator icons in location bar.
-  if (icon_str == "httpWarning") {
+  if (icon == Suggestion::Icon::kHttpWarning) {
     return ImageViewFromVectorIcon(omnibox::kHttpIcon, kIconSize);
   }
 
-  if (icon_str == "httpsInvalid") {
+  if (icon == Suggestion::Icon::kHttpsInvalid) {
     return std::make_unique<views::ImageView>(
         ui::ImageModel::FromVectorIcon(vector_icons::kNotSecureWarningIcon,
                                        ui::kColorAlertHighSeverity, kIconSize));
   }
 
-  if (icon_str == "keyIcon") {
+  if (icon == Suggestion::Icon::kKey) {
     return ImageViewFromVectorIcon(kKeyIcon, kIconSize);
   }
 
-  if (icon_str == "editIcon") {
+  if (icon == Suggestion::Icon::kEdit) {
     return ImageViewFromVectorIcon(vector_icons::kEditIcon, kIconSize);
   }
 
-  if (icon_str == "codeIcon") {
+  if (icon == Suggestion::Icon::kCode) {
     return ImageViewFromVectorIcon(vector_icons::kCodeIcon, kIconSize);
   }
 
-  if (icon_str == "locationIcon") {
+  if (icon == Suggestion::Icon::kLocation) {
     return ImageViewFromVectorIcon(vector_icons::kLocationOnIcon, kIconSize);
   }
 
-  if (icon_str == "deleteIcon") {
+  if (icon == Suggestion::Icon::kDelete) {
     return ImageViewFromVectorIcon(kTrashCanLightIcon, kIconSize);
   }
 
-  if (icon_str == "clearIcon") {
+  if (icon == Suggestion::Icon::kClear) {
     return ImageViewFromVectorIcon(kBackspaceIcon, kIconSize);
   }
 
-  if (icon_str == "undoIcon") {
+  if (icon == Suggestion::Icon::kUndo) {
     return ImageViewFromVectorIcon(vector_icons::kUndoIcon, kIconSize);
   }
 
-  if (icon_str == "globeIcon") {
+  if (icon == Suggestion::Icon::kGlobe) {
     return ImageViewFromVectorIcon(kGlobeIcon, kIconSize);
   }
 
-  if (icon_str == "magicIcon") {
+  if (icon == Suggestion::Icon::kMagic) {
     return ImageViewFromVectorIcon(vector_icons::kMagicButtonIcon, kIconSize);
   }
 
-  if (icon_str == "accountIcon") {
+  if (icon == Suggestion::Icon::kAccount) {
     return ImageViewFromVectorIcon(kAccountCircleIcon, kIconSize);
   }
 
-  if (icon_str == "settingsIcon") {
+  if (icon == Suggestion::Icon::kSettings) {
     return ImageViewFromVectorIcon(omnibox::kProductIcon, kIconSize);
   }
 
-  if (icon_str == "empty") {
+  if (icon == Suggestion::Icon::kEmpty) {
     return ImageViewFromVectorIcon(omnibox::kHttpIcon, kIconSize);
   }
 
-  if (icon_str == "device") {
+  if (icon == Suggestion::Icon::kDevice) {
     return ImageViewFromVectorIcon(kDevicesIcon, kIconSize);
   }
 
-  if (icon_str == "google") {
+  if (icon == Suggestion::Icon::kGoogle) {
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
     return ImageViewFromImageSkia(gfx::CreateVectorIcon(
         vector_icons::kGoogleGLogoIcon, kIconSize, gfx::kPlaceholderColor));
@@ -200,7 +200,7 @@
 #endif
   }
 
-  if (icon_str == "penSparkIcon") {
+  if (icon == Suggestion::Icon::kPenSpark) {
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
     return ImageViewFromVectorIcon(vector_icons::kPenSparkIcon, kIconSize);
 #else
@@ -208,18 +208,19 @@
 #endif
   }
 
-  if (icon_str == "googlePasswordManager") {
+  if (icon == Suggestion::Icon::kGooglePasswordManager) {
     return ImageViewFromVectorIcon(GooglePasswordManagerVectorIcon(),
                                    kGooglePasswordManagerIconSize);
   }
 
 #if !BUILDFLAG(GOOGLE_CHROME_BRANDING)
-  if (icon_str == "googlePay" || icon_str == "googlePayDark") {
+  if (icon == Suggestion::Icon::kGooglePay ||
+      icon == Suggestion::Icon::kGooglePayDark) {
     return nullptr;
   }
 #endif
   // For other suggestion entries, get icon from PNG files.
-  int icon_id = GetIconResourceID(icon_str);
+  int icon_id = GetIconResourceID(icon);
   DCHECK_NE(icon_id, 0);
   return ImageViewFromImageSkia(
       *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(icon_id));
diff --git a/chrome/browser/ui/views/autofill/popup/popup_row_strategy_unittest.cc b/chrome/browser/ui/views/autofill/popup/popup_row_strategy_unittest.cc
index 6820bd5..3df6358 100644
--- a/chrome/browser/ui/views/autofill/popup/popup_row_strategy_unittest.cc
+++ b/chrome/browser/ui/views/autofill/popup/popup_row_strategy_unittest.cc
@@ -103,7 +103,8 @@
     suggestions.reserve(popup_item_ids.size());
     for (PopupItemId popup_item_id : popup_item_ids) {
       // Create a suggestion with empty labels.
-      suggestions.emplace_back("Main text", "", "", popup_item_id);
+      suggestions.emplace_back("Main text", "", Suggestion::Icon::kNoIcon,
+                               popup_item_id);
     }
     controller().set_suggestions(std::move(suggestions));
   }
diff --git a/chrome/browser/ui/views/autofill/popup/popup_row_view_unittest.cc b/chrome/browser/ui/views/autofill/popup/popup_row_view_unittest.cc
index e587e23..72a7b05a 100644
--- a/chrome/browser/ui/views/autofill/popup/popup_row_view_unittest.cc
+++ b/chrome/browser/ui/views/autofill/popup/popup_row_view_unittest.cc
@@ -413,8 +413,9 @@
 }
 
 TEST_F(PopupRowViewTest, ContentViewA11yAttributes) {
-  ShowView(/*line_number=*/0, {Suggestion("dummy_value", "dummy_label", "",
-                                          PopupItemId::kAddressEntry)});
+  ShowView(/*line_number=*/0,
+           {Suggestion("dummy_value", "dummy_label", Suggestion::Icon::kNoIcon,
+                       PopupItemId::kAddressEntry)});
 
   views::ViewAccessibility& accessibility =
       row_view().GetContentView().GetViewAccessibility();
diff --git a/chrome/browser/ui/views/autofill/popup/popup_view_views_browsertest.cc b/chrome/browser/ui/views/autofill/popup/popup_view_views_browsertest.cc
index 3b8450d..a4039f4 100644
--- a/chrome/browser/ui/views/autofill/popup/popup_view_views_browsertest.cc
+++ b/chrome/browser/ui/views/autofill/popup/popup_view_views_browsertest.cc
@@ -34,25 +34,27 @@
 
 std::vector<Suggestion> CreateAutofillProfileSuggestions() {
   std::vector<Suggestion> suggestions;
-  suggestions.emplace_back("123 Apple St.", "Charles", "accountIcon",
+  suggestions.emplace_back("123 Apple St.", "Charles",
+                           Suggestion::Icon::kAccount,
                            PopupItemId::kAddressEntry);
-  suggestions.emplace_back("3734 Elvis Presley Blvd.", "Elvis", "accountIcon",
+  suggestions.emplace_back("3734 Elvis Presley Blvd.", "Elvis",
+                           Suggestion::Icon::kAccount,
                            PopupItemId::kAddressEntry);
 
   suggestions.emplace_back(PopupItemId::kSeparator);
 
   Suggestion settings(l10n_util::GetStringUTF16(IDS_AUTOFILL_MANAGE_ADDRESSES));
   settings.popup_item_id = PopupItemId::kAutofillOptions;
-  settings.icon = "settingsIcon";
+  settings.icon = Suggestion::Icon::kSettings;
   suggestions.push_back(std::move(settings));
 
   return suggestions;
 }
 
 std::vector<Suggestion> CreateAutocompleteSuggestions() {
-  return {Suggestion("Autocomplete entry 1", "", "",
+  return {Suggestion("Autocomplete entry 1", "", Suggestion::Icon::kNoIcon,
                      PopupItemId::kAutocompleteEntry),
-          Suggestion("Autocomplete entry 2", "", "",
+          Suggestion("Autocomplete entry 2", "", Suggestion::Icon::kNoIcon,
                      PopupItemId::kAutocompleteEntry)};
 }
 
@@ -154,8 +156,8 @@
   entry1.additional_label =
       std::u16string(10, gfx::RenderText::kPasswordReplacementChar);
   entry1.popup_item_id = PopupItemId::kAccountStoragePasswordEntry;
-  entry1.icon = "globeIcon";
-  entry1.trailing_icon = "google";
+  entry1.icon = Suggestion::Icon::kGlobe;
+  entry1.trailing_icon = Suggestion::Icon::kGoogle;
   suggestions.push_back(std::move(entry1));
 
   // A profile store entry.
@@ -164,8 +166,8 @@
   entry2.additional_label =
       std::u16string(6, gfx::RenderText::kPasswordReplacementChar);
   entry2.popup_item_id = PopupItemId::kPasswordEntry;
-  entry2.icon = "globeIcon";
-  entry2.trailing_icon = "";
+  entry2.icon = Suggestion::Icon::kGlobe;
+  entry2.trailing_icon = Suggestion::Icon::kNoIcon;
   suggestions.push_back(std::move(entry2));
 
   suggestions.emplace_back(PopupItemId::kSeparator);
@@ -174,8 +176,8 @@
   Suggestion settings(
       l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_MANAGE_PASSWORDS));
   settings.popup_item_id = PopupItemId::kAllSavedPasswordsEntry;
-  settings.icon = "settingsIcon";
-  settings.trailing_icon = "googlePasswordManager";
+  settings.icon = Suggestion::Icon::kSettings;
+  settings.trailing_icon = Suggestion::Icon::kGooglePasswordManager;
   suggestions.push_back(std::move(settings));
 
   PrepareSuggestions(std::move(suggestions));
diff --git a/chrome/browser/ui/views/autofill/popup/popup_view_views_unittest.cc b/chrome/browser/ui/views/autofill/popup/popup_view_views_unittest.cc
index aafa2ea..1c63b75 100644
--- a/chrome/browser/ui/views/autofill/popup/popup_view_views_unittest.cc
+++ b/chrome/browser/ui/views/autofill/popup/popup_view_views_unittest.cc
@@ -438,7 +438,8 @@
 #endif  // !BUILDFLAG(IS_MAC)
 
 TEST_F(PopupViewViewsTest, ClickDisabledEntry) {
-  Suggestion opt_int_suggestion("dummy_main_text", "", "",
+  Suggestion opt_int_suggestion("dummy_main_text", "",
+                                Suggestion::Icon::kNoIcon,
                                 PopupItemId::kPasswordAccountStorageOptIn);
   opt_int_suggestion.is_loading = Suggestion::IsLoading(true);
   controller().set_suggestions({opt_int_suggestion});
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view_interactive_uitest.cc b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view_interactive_uitest.cc
index 2e9c1de..f84cb303 100644
--- a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view_interactive_uitest.cc
@@ -416,14 +416,14 @@
   browser()->set_update_ui_immediately_for_testing();
   content::WebContents* unfocused_tab =
       browser()->tab_strip_model()->GetWebContentsAt(0);
-  content::TitleWatcher title_watcher(unfocused_tab, u"Updated Title");
+  std::u16string updated_title = u"Updated Title";
+  content::TitleWatcher title_watcher(unfocused_tab, updated_title);
   ASSERT_TRUE(
       content::ExecJs(unfocused_tab, "document.title = 'Updated Title';"));
-  // TODO: handle return value.
-  std::ignore = title_watcher.WaitAndGetTitle();
-  // The browser UI is updated by a PostTask() with a delay of zero seconds.
-  // However, the update will be visible when the run loop next idles after the
-  // title is updated. To ensure it's ran, lets wait until its idle.
+  ASSERT_EQ(title_watcher.WaitAndGetTitle(), updated_title);
+  // The browser UI is updated by a PostTask() with a delay of zero
+  // seconds. However, the update will be visible when the run loop next
+  // idles after the title is updated. To ensure it ran, wait until it's idle.
   base::RunLoop().RunUntilIdle();
 
   // Verify extensions menu content wasn't affected by checking the site
diff --git a/chrome/browser/ui/views/frame/browser_actions.cc b/chrome/browser/ui/views/frame/browser_actions.cc
index 3c1582c5..07acfe1e 100644
--- a/chrome/browser/ui/views/frame/browser_actions.cc
+++ b/chrome/browser/ui/views/frame/browser_actions.cc
@@ -4,18 +4,21 @@
 
 #include "chrome/browser/ui/views/frame/browser_actions.h"
 
+#include "base/check_op.h"
 #include "chrome/app/vector_icons/vector_icons.h"
 #include "chrome/browser/ui/actions/chrome_action_id.h"
 #include "chrome/browser/ui/actions/chrome_actions.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/side_panel/companion/companion_utils.h"
 #include "chrome/browser/ui/side_panel/side_panel_entry_id.h"
+#include "chrome/browser/ui/side_panel/side_panel_enums.h"
 #include "chrome/browser/ui/side_panel/side_panel_ui.h"
 #include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
 #include "chrome/browser/ui/views/page_info/page_info_view_factory.h"
 #include "chrome/browser/ui/views/side_panel/history_clusters/history_clusters_side_panel_coordinator.h"
 #include "chrome/browser/ui/views/side_panel/search_companion/search_companion_side_panel_coordinator.h"
+#include "chrome/browser/ui/views/side_panel/side_panel_util.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/feed/feed_feature_list.h"
 #include "components/history_clusters/core/features.h"
@@ -47,7 +50,13 @@
                  [](SidePanelEntryId id, Browser* browser,
                     actions::ActionItem* item,
                     actions::ActionInvocationContext context) {
-                   SidePanelUI::GetSidePanelUIForBrowser(browser)->Show(id);
+                   const SidePanelOpenTrigger open_trigger =
+                       static_cast<SidePanelOpenTrigger>(
+                           context.GetProperty(kSidePanelOpenTriggerKey));
+                   CHECK_GE(open_trigger, SidePanelOpenTrigger::kMinValue);
+                   CHECK_LE(open_trigger, SidePanelOpenTrigger::kMaxValue);
+                   SidePanelUI::GetSidePanelUIForBrowser(browser)->Show(
+                       id, open_trigger);
                  },
                  id, browser))
       .SetActionId(action_id)
diff --git a/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view.h b/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view.h
index db87ae7..7b344252 100644
--- a/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view.h
+++ b/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view.h
@@ -78,7 +78,8 @@
   void OnColorsChanged(SkColor foreground_color,
                        SkColor background_color) override;
   void UpdateCurrentAudioDevice(const std::string& current_device_id) override;
-  void ShowOrHideDeviceList() override;
+  void ShowDevices() override;
+  void HideDevices() override;
   bool IsDeviceSelectorExpanded() override;
 
   // Called when the audio device switching has become enabled or disabled.
@@ -118,8 +119,7 @@
   void UpdateVisibility();
   bool ShouldBeVisible() const;
   void CreateExpandButtonStrip(bool show_expand_button);
-  void ShowDevices();
-  void HideDevices();
+  void ShowOrHideDeviceList();
   void RemoveDevicesOfType(DeviceEntryUIType type);
   void OnCastDeviceSelected(const std::string& device_id);
   DeviceEntryUI* GetDeviceEntryUI(views::View* view) const;
diff --git a/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc b/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc
index 670ec08..bda0e1c 100644
--- a/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc
+++ b/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc
@@ -460,13 +460,14 @@
     absl::optional<actions::ActionId> action_id =
         GetActionItem(current_entry_->key())->GetActionId();
     CHECK(action_id.has_value());
-    actions_model->UpdatePinnedState(
-        action_id.value(), !actions_model->Contains(action_id.value()));
-    // TODO(b:299464014): Add metrics for pinned panels
+    const bool updated_pin_state = !actions_model->Contains(action_id.value());
+    actions_model->UpdatePinnedState(action_id.value(), updated_pin_state);
+    SidePanelUtil::RecordPinnedButtonClicked(current_entry_->key().id(),
+                                             updated_pin_state);
   } else {
     PrefService* const pref_service = profile->GetPrefs();
     if (pref_service) {
-      bool current_state = pref_service->GetBoolean(
+      const bool current_state = pref_service->GetBoolean(
           prefs::kSidePanelCompanionEntryPinnedToToolbar);
       pref_service->SetBoolean(prefs::kSidePanelCompanionEntryPinnedToToolbar,
                                !current_state);
diff --git a/chrome/browser/ui/views/side_panel/side_panel_util.cc b/chrome/browser/ui/views/side_panel/side_panel_util.cc
index dbf6fd1..ec7ea8ed 100644
--- a/chrome/browser/ui/views/side_panel/side_panel_util.cc
+++ b/chrome/browser/ui/views/side_panel/side_panel_util.cc
@@ -34,12 +34,23 @@
 #include "components/prefs/pref_service.h"
 #include "components/user_notes/user_notes_features.h"
 #include "ui/accessibility/accessibility_features.h"
+#include "ui/actions/actions.h"
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
 #include "chrome/browser/ui/views/side_panel/extensions/extension_side_panel_manager.h"
 #include "extensions/common/extension_features.h"
 #endif
 
+namespace {
+constexpr std::underlying_type_t<SidePanelOpenTrigger>
+    kInvalidSidePanelOpenTrigger = -1;
+}
+
+DEFINE_UI_CLASS_PROPERTY_TYPE(SidePanelOpenTrigger)
+DEFINE_UI_CLASS_PROPERTY_KEY(std::underlying_type_t<SidePanelOpenTrigger>,
+                             kSidePanelOpenTriggerKey,
+                             kInvalidSidePanelOpenTrigger)
+
 // static
 void SidePanelUtil::PopulateGlobalEntries(Browser* browser,
                                           SidePanelRegistry* global_registry) {
@@ -220,3 +231,10 @@
 void SidePanelUtil::RecordComboboxShown() {
   base::UmaHistogramBoolean("SidePanel.ComboboxMenuShown", true);
 }
+
+void SidePanelUtil::RecordPinnedButtonClicked(SidePanelEntry::Id id,
+                                              bool is_pinned) {
+  base::RecordComputedAction(base::StrCat(
+      {"SidePanel.", SidePanelEntryIdToHistogramName(id), ".",
+       is_pinned ? "Pinned" : "Unpinned", ".BySidePanelHeaderButton"}));
+}
diff --git a/chrome/browser/ui/views/side_panel/side_panel_util.h b/chrome/browser/ui/views/side_panel/side_panel_util.h
index d322fe6..24a5ea9 100644
--- a/chrome/browser/ui/views/side_panel/side_panel_util.h
+++ b/chrome/browser/ui/views/side_panel/side_panel_util.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_SIDE_PANEL_UTIL_H_
 #define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_SIDE_PANEL_UTIL_H_
 
+#include <type_traits>
+
 #include "base/time/time.h"
 #include "chrome/browser/ui/side_panel/side_panel_entry_id.h"
 #include "chrome/browser/ui/side_panel/side_panel_enums.h"
@@ -58,6 +60,11 @@
       SidePanelEntry::Id id,
       absl::optional<SidePanelOpenTrigger> trigger);
   static void RecordComboboxShown();
+  static void RecordPinnedButtonClicked(SidePanelEntry::Id id, bool is_pinned);
 };
 
+extern const ui::ClassProperty<
+    std::underlying_type_t<SidePanelOpenTrigger>>* const
+    kSidePanelOpenTriggerKey;
+
 #endif  // CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_SIDE_PANEL_UTIL_H_
diff --git a/chrome/browser/ui/views/tabs/new_tab_button.cc b/chrome/browser/ui/views/tabs/new_tab_button.cc
index 29cf11f..3e02d54a4 100644
--- a/chrome/browser/ui/views/tabs/new_tab_button.cc
+++ b/chrome/browser/ui/views/tabs/new_tab_button.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/ui/layout_constants.h"
 #include "chrome/browser/ui/tabs/tab_types.h"
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
+#include "chrome/browser/ui/views/frame/top_container_background.h"
 #include "chrome/browser/ui/views/tabs/browser_tab_strip_controller.h"
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
 #include "chrome/grit/generated_resources.h"
@@ -53,7 +54,7 @@
   // views::HighlightPathGenerator:
   SkPath GetHighlightPath(const views::View* view) override {
     return static_cast<const NewTabButton*>(view)->GetBorderPath(
-        view->GetContentsBounds().origin(), 1.0f, false);
+        view->GetContentsBounds().origin(), false);
   }
 };
 
@@ -61,6 +62,10 @@
     : views::ImageButton(std::move(callback)), tab_strip_(tab_strip) {
   SetAnimateOnStateChange(true);
 
+  // If there is an image for the NewTabButton it is set by the theme. Theme
+  // images should not be flipped for RTL.
+  SetFlipCanvasOnPaintForRTLUI(false);
+
   foreground_frame_active_color_id_ = kColorNewTabButtonForegroundFrameActive;
   foreground_frame_inactive_color_id_ =
       kColorNewTabButtonForegroundFrameInactive;
@@ -130,24 +135,20 @@
 }
 
 SkPath NewTabButton::GetBorderPath(const gfx::Point& origin,
-                                   float scale,
                                    bool extend_to_top) const {
-  gfx::PointF scaled_origin(origin);
-  scaled_origin.Scale(scale);
-  const float radius = GetCornerRadius() * scale;
+  const float radius = GetCornerRadius();
 
   SkPath path;
   if (extend_to_top) {
-    path.moveTo(scaled_origin.x(), 0);
+    path.moveTo(origin.x(), 0);
     const float diameter = radius * 2;
     path.rLineTo(diameter, 0);
-    path.rLineTo(0, scaled_origin.y() + radius);
+    path.rLineTo(0, origin.y() + radius);
     path.rArcTo(radius, radius, 0, SkPath::kSmall_ArcSize, SkPathDirection::kCW,
                 -diameter, 0);
     path.close();
   } else {
-    path.addCircle(scaled_origin.x() + radius, scaled_origin.y() + radius,
-                   radius);
+    path.addCircle(origin.x() + radius, origin.y() + radius, radius);
   }
   return path;
 }
@@ -206,8 +207,6 @@
 }
 
 void NewTabButton::PaintButtonContents(gfx::Canvas* canvas) {
-  gfx::ScopedCanvas scoped_canvas(canvas);
-  canvas->Translate(GetContentsBounds().OffsetFromOrigin());
   PaintFill(canvas);
   PaintIcon(canvas);
 }
@@ -225,53 +224,48 @@
   gfx::Point origin = GetContentsBounds().origin();
   if (base::i18n::IsRTL())
     origin.set_x(GetInsets().right());
-  const float scale = GetWidget()->GetCompositor()->device_scale_factor();
-  SkPath border = GetBorderPath(origin, scale,
-                                tab_strip_->controller()->IsFrameCondensed());
-  mask->addPath(border, SkMatrix::Scale(1 / scale, 1 / scale));
+  SkPath border =
+      GetBorderPath(origin, tab_strip_->controller()->IsFrameCondensed());
+  mask->addPath(border);
   return true;
 }
 
 void NewTabButton::PaintFill(gfx::Canvas* canvas) const {
   gfx::ScopedCanvas scoped_canvas(canvas);
-  canvas->UndoDeviceScaleFactor();
-  cc::PaintFlags flags;
-  flags.setAntiAlias(true);
 
-  const float scale = canvas->image_scale();
   const absl::optional<int> bg_id =
       tab_strip_->GetCustomBackgroundId(BrowserFrameActiveState::kUseCurrent);
   if (bg_id.has_value()) {
-    float x_scale = scale;
-    const gfx::Rect& contents_bounds = GetContentsBounds();
-    gfx::RectF bounds_in_tab_strip(GetLocalBounds());
-    View::ConvertRectToTarget(this, tab_strip_, &bounds_in_tab_strip);
-    int x = bounds_in_tab_strip.x() + contents_bounds.x() +
-            tab_strip_->GetBackgroundOffset();
-    if (base::i18n::IsRTL()) {
-      // The new tab background is mirrored in RTL mode, but the theme
-      // background should never be mirrored. Mirror it here to compensate.
-      x_scale = -scale;
-      // Offset by |width| such that the same region is painted as if there
-      // was no flip.
-      x += contents_bounds.width();
-    }
+    // The shape and location of the background texture is defined by a clip
+    // path. This needs to be translated to center it in the view.
+    auto path = GetBorderPath(gfx::Point(), false);
+    auto offset = GetContentsBounds().OffsetFromOrigin();
+    path.offset(offset.x(), offset.y());
+    canvas->ClipPath(path, /*do_anti_alias=*/true);
 
-    canvas->InitPaintFlagsForTiling(
-        *GetThemeProvider()->GetImageSkiaNamed(bg_id.value()), x,
-        contents_bounds.y(), x_scale, scale, 0, 0, SkTileMode::kRepeat,
-        SkTileMode::kRepeat, &flags);
+    // But the background image itself must not be translated in order to align
+    // with the same background image painted across different views.
+    TopContainerBackground::PaintThemeAlignedImage(
+        canvas, this,
+        BrowserView::GetBrowserViewForBrowser(tab_strip_->GetBrowser()),
+        GetThemeProvider()->GetImageSkiaNamed(bg_id.value()));
   } else {
+    // In the non themed-image case, we simply draw a solid color button. Note
+    // that cc::PaintFlags defaults to fill.
+    cc::PaintFlags flags;
+    flags.setAntiAlias(true);
+    canvas->Translate(GetContentsBounds().OffsetFromOrigin());
     flags.setColor(GetColorProvider()->GetColor(
         GetWidget()->ShouldPaintAsActive()
             ? background_frame_active_color_id_
             : background_frame_inactive_color_id_));
+    canvas->DrawPath(GetBorderPath(gfx::Point(), false), flags);
   }
-
-  canvas->DrawPath(GetBorderPath(gfx::Point(), scale, false), flags);
 }
 
 void NewTabButton::PaintIcon(gfx::Canvas* canvas) {
+  gfx::ScopedCanvas scoped_canvas(canvas);
+  canvas->Translate(GetContentsBounds().OffsetFromOrigin());
   cc::PaintFlags flags;
   flags.setAntiAlias(true);
   flags.setColor(GetForegroundColor());
diff --git a/chrome/browser/ui/views/tabs/new_tab_button.h b/chrome/browser/ui/views/tabs/new_tab_button.h
index 924823d..68ba0a8 100644
--- a/chrome/browser/ui/views/tabs/new_tab_button.h
+++ b/chrome/browser/ui/views/tabs/new_tab_button.h
@@ -61,10 +61,9 @@
   // Returns the radius to use for the button corners.
   virtual int GetCornerRadius() const;
 
-  // Returns the path for the given |origin| and |scale|.  If |extend_to_top| is
+  // Returns the path for the given |origin|.  If |extend_to_top| is
   // true, the path is extended vertically to y = 0.
   virtual SkPath GetBorderPath(const gfx::Point& origin,
-                               float scale,
                                bool extend_to_top) const;
 
   // views::ImageButton:
@@ -88,6 +87,11 @@
   // views::MaskedTargeterDelegate:
   bool GetHitTestMask(SkPath* mask) const override;
 
+  // The NewTabButton consists of a foreground image on top of a background
+  // texture. First we paint the background with PaintFill. This is clipped to a
+  // circle to make the button appear circular. Then we paint the
+  // foreground image with PaintIcon.
+  //
   // Paints the fill region of the button into |canvas|.
   void PaintFill(gfx::Canvas* canvas) const;
 
diff --git a/chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container.cc b/chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container.cc
index 3496649..950943e 100644
--- a/chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container.cc
+++ b/chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container.cc
@@ -6,14 +6,18 @@
 
 #include <memory>
 #include <string>
+#include <type_traits>
 
 #include "base/functional/bind.h"
 #include "base/memory/raw_ptr.h"
+#include "base/metrics/user_metrics.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser_element_identifiers.h"
 #include "chrome/browser/ui/layout_constants.h"
+#include "chrome/browser/ui/side_panel/side_panel_enums.h"
 #include "chrome/browser/ui/views/frame/browser_actions.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/side_panel/side_panel_util.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_button.h"
 #include "chrome/grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -26,6 +30,12 @@
 #include "ui/views/layout/layout_types.h"
 #include "ui/views/view_class_properties.h"
 
+namespace {
+void RecordPinnedActionsCount(int count) {
+  base::UmaHistogramCounts100("Browser.Actions.PinnedActionsCount", count);
+}
+}  // namespace
+
 ///////////////////////////////////////////////////////////////////////////////
 // PinnedToolbarActionsContainer::PinnedActionToolbarButton:
 
@@ -77,7 +87,15 @@
 }
 
 void PinnedToolbarActionsContainer::PinnedActionToolbarButton::ButtonPressed() {
-  action_item_->InvokeAction();
+  base::RecordAction(
+      base::UserMetricsAction("Actions.PinnedToolbarButtonActivation"));
+  action_item_->InvokeAction(
+      actions::ActionInvocationContext::Builder()
+          .SetProperty(
+              kSidePanelOpenTriggerKey,
+              static_cast<std::underlying_type_t<SidePanelOpenTrigger>>(
+                  SidePanelOpenTrigger::kPinnedEntryToolbarButton))
+          .Build());
 }
 
 bool PinnedToolbarActionsContainer::PinnedActionToolbarButton::IsActive() {
@@ -215,12 +233,14 @@
   }
   AddPinnedActionButtonFor(id);
   GetSidePanelCoordinator()->UpdateHeaderPinButtonState();
+  RecordPinnedActionsCount(model_->pinned_action_ids().size());
 }
 
 void PinnedToolbarActionsContainer::OnActionRemoved(
     const actions::ActionId& id) {
   RemovePinnedActionButtonFor(id);
   GetSidePanelCoordinator()->UpdateHeaderPinButtonState();
+  RecordPinnedActionsCount(model_->pinned_action_ids().size());
 }
 
 void PinnedToolbarActionsContainer::OnActionMoved(const actions::ActionId& id,
diff --git a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc
index be8e2d3a..beac3d2 100644
--- a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc
+++ b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc
@@ -290,7 +290,13 @@
   EXPECT_EQ(menu_button->width(), original_menu_button_width);
 }
 
-IN_PROC_BROWSER_TEST_F(WebAppFrameToolbarBrowserTest, ThemeChange) {
+// TODO(crbug.com/1500064): Re-enable this test
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+#define MAYBE_ThemeChange DISABLED_ThemeChange
+#else
+#define MAYBE_ThemeChange ThemeChange
+#endif
+IN_PROC_BROWSER_TEST_F(WebAppFrameToolbarBrowserTest, MAYBE_ThemeChange) {
   ASSERT_TRUE(https_server()->Start());
   const GURL app_url = https_server()->GetURL("/banners/theme-color.html");
   helper()->InstallAndLaunchWebApp(browser(), app_url);
diff --git a/chrome/browser/ui/webui/ash/login/quick_start_screen_handler.cc b/chrome/browser/ui/webui/ash/login/quick_start_screen_handler.cc
index 90e1f7e..d0b4a90 100644
--- a/chrome/browser/ui/webui/ash/login/quick_start_screen_handler.cc
+++ b/chrome/browser/ui/webui/ash/login/quick_start_screen_handler.cc
@@ -36,16 +36,6 @@
   CallExternalAPI("showConnectingToWifi");
 }
 
-void QuickStartScreenHandler::ShowConnectedToWifi(
-    std::string ssid,
-    absl::optional<std::string> password) {
-  if (password.has_value()) {
-    CallExternalAPI("showConnectedToWifi", ssid, password.value());
-  } else {
-    CallExternalAPI("showConnectedToWifi", ssid);
-  }
-}
-
 void QuickStartScreenHandler::ShowTransferringGaiaCredentials() {
   CallExternalAPI("showTransferringGaiaCredentials");
 }
diff --git a/chrome/browser/ui/webui/ash/login/quick_start_screen_handler.h b/chrome/browser/ui/webui/ash/login/quick_start_screen_handler.h
index 3b7c162..512b93e 100644
--- a/chrome/browser/ui/webui/ash/login/quick_start_screen_handler.h
+++ b/chrome/browser/ui/webui/ash/login/quick_start_screen_handler.h
@@ -30,8 +30,6 @@
   virtual void SetQRCode(base::Value::List blob) = 0;
   virtual void SetDiscoverableName(const std::string& discoverable_name) = 0;
   virtual void ShowConnectingToWifi() = 0;
-  virtual void ShowConnectedToWifi(std::string ssid,
-                                   absl::optional<std::string> password) = 0;
   virtual void ShowTransferringGaiaCredentials() = 0;
   virtual void ShowFidoAssertionReceived(std::string email) = 0;
 };
@@ -55,8 +53,6 @@
   void SetQRCode(base::Value::List blob) override;
   void SetDiscoverableName(const std::string& discoverable_name) override;
   void ShowConnectingToWifi() override;
-  void ShowConnectedToWifi(std::string ssid,
-                           absl::optional<std::string> password) override;
   void ShowTransferringGaiaCredentials() override;
   void ShowFidoAssertionReceived(std::string email) override;
 
diff --git a/chrome/browser/ui/webui/ash/smb_shares/smb_credentials_dialog.cc b/chrome/browser/ui/webui/ash/smb_shares/smb_credentials_dialog.cc
index b2c1d6f0..1f3f0a7 100644
--- a/chrome/browser/ui/webui/ash/smb_shares/smb_credentials_dialog.cc
+++ b/chrome/browser/ui/webui/ash/smb_shares/smb_credentials_dialog.cc
@@ -15,7 +15,6 @@
 #include "chrome/common/webui_url_constants.h"
 #include "chrome/grit/browser_resources.h"
 #include "chrome/grit/generated_resources.h"
-#include "chromeos/constants/chromeos_features.h"
 #include "components/strings/grit/components_strings.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
@@ -24,8 +23,7 @@
 namespace ash::smb_dialog {
 namespace {
 
-constexpr int kSmbCredentialsDialogHeight = 230;
-constexpr int kSmbCredentialsDialogHeightWithJellyOn = 295;
+constexpr int kSmbCredentialsDialogHeight = 295;
 
 void AddSmbCredentialsDialogStrings(content::WebUIDataSource* html_source) {
   static const struct {
@@ -41,8 +39,6 @@
   for (const auto& entry : localized_strings) {
     html_source->AddLocalizedString(entry.name, entry.id);
   }
-  bool is_jelly_enabled = chromeos::features::IsJellyEnabled();
-  html_source->AddBoolean("isJellyEnabled", is_jelly_enabled);
 }
 
 std::string GetDialogId(const std::string& mount_id) {
@@ -99,9 +95,7 @@
 
 void SmbCredentialsDialog::GetDialogSize(gfx::Size* size) const {
   size->SetSize(SystemWebDialogDelegate::kDialogWidth,
-                chromeos::features::IsJellyEnabled()
-                    ? kSmbCredentialsDialogHeightWithJellyOn
-                    : kSmbCredentialsDialogHeight);
+                kSmbCredentialsDialogHeight);
 }
 
 std::string SmbCredentialsDialog::GetDialogArgs() const {
diff --git a/chrome/browser/ui/webui/ash/smb_shares/smb_share_dialog.cc b/chrome/browser/ui/webui/ash/smb_shares/smb_share_dialog.cc
index f9c1c53d..aaba527 100644
--- a/chrome/browser/ui/webui/ash/smb_shares/smb_share_dialog.cc
+++ b/chrome/browser/ui/webui/ash/smb_shares/smb_share_dialog.cc
@@ -26,8 +26,7 @@
 namespace ash::smb_dialog {
 namespace {
 
-constexpr int kSmbShareDialogHeight = 515;
-constexpr int kSmbShareDialogHeightWithJellyOn = 570;
+constexpr int kSmbShareDialogHeight = 570;
 
 void AddSmbSharesStrings(content::WebUIDataSource* html_source) {
   // Add strings specific to smb_dialog.
@@ -62,10 +61,7 @@
 SmbShareDialog::~SmbShareDialog() = default;
 
 void SmbShareDialog::GetDialogSize(gfx::Size* size) const {
-  size->SetSize(SystemWebDialogDelegate::kDialogWidth,
-                chromeos::features::IsJellyEnabled()
-                    ? kSmbShareDialogHeightWithJellyOn
-                    : kSmbShareDialogHeight);
+  size->SetSize(SystemWebDialogDelegate::kDialogWidth, kSmbShareDialogHeight);
 }
 
 SmbShareDialogUI::SmbShareDialogUI(content::WebUI* web_ui)
@@ -94,8 +90,6 @@
       user_manager::UserManager::Get()->IsLoggedInAsManagedGuestSession();
   source->AddBoolean("isGuest", is_guest);
 
-  bool is_jelly_enabled = chromeos::features::IsJellyEnabled();
-  source->AddBoolean("isJellyEnabled", is_jelly_enabled);
   source->AddBoolean("isCrosComponentsEnabled",
                      chromeos::features::IsCrosComponentsEnabled());
 
diff --git a/chrome/browser/ui/webui/dlp_internals/dlp_internals.mojom b/chrome/browser/ui/webui/dlp_internals/dlp_internals.mojom
index 02df1de..a04a80c 100644
--- a/chrome/browser/ui/webui/dlp_internals/dlp_internals.mojom
+++ b/chrome/browser/ui/webui/dlp_internals/dlp_internals.mojom
@@ -75,6 +75,77 @@
   array<RenderFrameHostInfo> frames_info;
 };
 
+// Represents DLP policy event destination.
+// See components/enterprise/data_controls/dlp_policy_event.proto
+// for DlpPolicyEventDestination.
+struct EventDestination {
+  // Represents DLP policy components.
+  // See components/enterprise/data_controls/component.h for Component enum.
+  enum Component {
+    kUndefinedComponent = 0,
+    kArc = 1,
+    kCrostini = 2,
+    kPluginVm = 3,
+    kUsb = 4,
+    kDrive = 5,
+    kOnedrive = 6,
+  };
+
+  // Either |url| or |component| should be set.
+  string? url_pattern;
+  Component? component;
+};
+
+// Represents DLP policy event.
+// See components/enterprise/data_controls/dlp_policy_event.proto
+// for DlpPolicyEvent.
+struct DlpEvent {
+  // The restriction that was triggered.
+  enum Restriction {
+    kUndefinedRestriction = 0,
+    kClipboard = 1,
+    kScreenshot = 2,
+    kScreencast = 3,
+    kPrinting = 4,
+    kEprivacy = 5,
+    kFiles = 6,
+  };
+
+  // The mode of the applied restriction.
+  enum Mode {
+    kUndefinedMode = 0,
+    kBlock = 1,
+    kReport = 2,
+    kWarn = 3,
+    kWarnProceed = 4,
+  };
+
+  // Type of user session from which the event is reported.
+  enum UserType {
+    kUndefinedUserType = 0,
+    kRegular = 1,
+    kManagedGuest = 2,
+    kKiosk = 3,
+  };
+
+  string? source_pattern;
+  EventDestination? destination;
+  Restriction? restriction;
+  Mode? mode;
+  int64? timestamp_micro;
+  UserType? user_type;
+  string? content_name;
+  string? triggered_rule_name;
+  string? triggered_rule_id;
+};
+
+// Observer interface to receive updates about DLP reporting events.
+// This interface is implement in Javascript in chrome://dlp-internals WebUI.
+interface ReportingObserver {
+  // Called when an event is reported.
+  OnReportEvent(DlpEvent event);
+};
+
 // Browser interface for the page. Consists of calls for data and hooks for
 // interactivity.
 interface PageHandler {
@@ -83,4 +154,7 @@
 
   // Returns content restrictions information for all the tracked WebContents.
   GetContentRestrictionsInfo() => (array<WebContentsInfo> web_contents_info);
+
+  // Allows the caller to observe reporting events.
+  ObserveReporting(pending_remote<ReportingObserver> observer);
 };
\ No newline at end of file
diff --git a/chrome/browser/ui/webui/dlp_internals/dlp_internals_page_handler.cc b/chrome/browser/ui/webui/dlp_internals/dlp_internals_page_handler.cc
index 75ac202..1bf00173 100644
--- a/chrome/browser/ui/webui/dlp_internals/dlp_internals_page_handler.cc
+++ b/chrome/browser/ui/webui/dlp_internals/dlp_internals_page_handler.cc
@@ -7,8 +7,11 @@
 #include "base/check.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_content_manager.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_content_restriction_set.h"
+#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
+#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/dlp_internals/dlp_internals.mojom.h"
+#include "components/enterprise/data_controls/dlp_policy_event.pb.h"
 #include "components/enterprise/data_controls/rule.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/receiver.h"
@@ -78,6 +81,93 @@
   return rfh_info_mojo_arr;
 }
 
+dlp_internals::mojom::DlpEvent::Restriction EventRestrictionToMojo(
+    DlpPolicyEvent::Restriction restriction) {
+  switch (restriction) {
+    case DlpPolicyEvent_Restriction_UNDEFINED_RESTRICTION:
+      return dlp_internals::mojom::DlpEvent::Restriction::kUndefinedRestriction;
+    case DlpPolicyEvent_Restriction_CLIPBOARD:
+      return dlp_internals::mojom::DlpEvent::Restriction::kClipboard;
+    case DlpPolicyEvent_Restriction_SCREENSHOT:
+      return dlp_internals::mojom::DlpEvent::Restriction::kScreenshot;
+    case DlpPolicyEvent_Restriction_SCREENCAST:
+      return dlp_internals::mojom::DlpEvent::Restriction::kScreencast;
+    case DlpPolicyEvent_Restriction_PRINTING:
+      return dlp_internals::mojom::DlpEvent::Restriction::kPrinting;
+    case DlpPolicyEvent_Restriction_EPRIVACY:
+      return dlp_internals::mojom::DlpEvent::Restriction::kEprivacy;
+    case DlpPolicyEvent_Restriction_FILES:
+      return dlp_internals::mojom::DlpEvent::Restriction::kFiles;
+  }
+}
+
+dlp_internals::mojom::DlpEvent::UserType EventUserTypeToMojo(
+    DlpPolicyEvent::UserType restriction) {
+  switch (restriction) {
+    case DlpPolicyEvent_UserType_REGULAR:
+      return dlp_internals::mojom::DlpEvent::UserType::kRegular;
+    case DlpPolicyEvent_UserType_MANAGED_GUEST:
+      return dlp_internals::mojom::DlpEvent::UserType::kManagedGuest;
+    case DlpPolicyEvent_UserType_KIOSK:
+      return dlp_internals::mojom::DlpEvent::UserType::kKiosk;
+    case DlpPolicyEvent_UserType_UNDEFINED_USER_TYPE:
+      return dlp_internals::mojom::DlpEvent::UserType::kUndefinedUserType;
+  }
+}
+
+dlp_internals::mojom::DlpEvent::Mode EventModeToMojo(
+    DlpPolicyEvent::Mode mode) {
+  switch (mode) {
+    case DlpPolicyEvent_Mode_UNDEFINED_MODE:
+      return dlp_internals::mojom::DlpEvent::Mode::kUndefinedMode;
+    case DlpPolicyEvent_Mode_BLOCK:
+      return dlp_internals::mojom::DlpEvent::Mode::kBlock;
+    case DlpPolicyEvent_Mode_REPORT:
+      return dlp_internals::mojom::DlpEvent::Mode::kReport;
+    case DlpPolicyEvent_Mode_WARN:
+      return dlp_internals::mojom::DlpEvent::Mode::kWarn;
+    case DlpPolicyEvent_Mode_WARN_PROCEED:
+      return dlp_internals::mojom::DlpEvent::Mode::kWarnProceed;
+  }
+}
+
+dlp_internals::mojom::EventDestination::Component
+EventDestinationComponentToMojo(
+    DlpPolicyEventDestination::Component component) {
+  switch (component) {
+    case DlpPolicyEventDestination_Component_UNDEFINED_COMPONENT:
+      return dlp_internals::mojom::EventDestination::Component::
+          kUndefinedComponent;
+    case DlpPolicyEventDestination_Component_ARC:
+      return dlp_internals::mojom::EventDestination::Component::kArc;
+    case DlpPolicyEventDestination_Component_CROSTINI:
+      return dlp_internals::mojom::EventDestination::Component::kCrostini;
+    case DlpPolicyEventDestination_Component_PLUGIN_VM:
+      return dlp_internals::mojom::EventDestination::Component::kPluginVm;
+    case DlpPolicyEventDestination_Component_USB:
+      return dlp_internals::mojom::EventDestination::Component::kUsb;
+    case DlpPolicyEventDestination_Component_DRIVE:
+      return dlp_internals::mojom::EventDestination::Component::kDrive;
+    case DlpPolicyEventDestination_Component_ONEDRIVE:
+      return dlp_internals::mojom::EventDestination::Component::kOnedrive;
+  }
+}
+
+dlp_internals::mojom::EventDestinationPtr EventDestinationToMojo(
+    DlpPolicyEventDestination destination) {
+  auto destination_mojo = dlp_internals::mojom::EventDestination::New();
+
+  if (destination.has_component()) {
+    destination_mojo->component =
+        EventDestinationComponentToMojo(destination.component());
+  }
+
+  if (destination.has_url()) {
+    destination_mojo->url_pattern = destination.url();
+  }
+  return destination_mojo;
+}
+
 }  // namespace
 
 DlpInternalsPageHandler::DlpInternalsPageHandler(
@@ -85,6 +175,13 @@
     Profile* profile)
     : receiver_(this, std::move(receiver)), profile_(profile) {
   DCHECK(profile_);
+
+  auto* rules_manager = DlpRulesManagerFactory::GetForPrimaryProfile();
+  auto* reporting_manager =
+      rules_manager ? rules_manager->GetReportingManager() : nullptr;
+  if (reporting_manager) {
+    reporting_observation_.Observe(reporting_manager);
+  }
 }
 
 DlpInternalsPageHandler::~DlpInternalsPageHandler() = default;
@@ -165,4 +262,53 @@
   std::move(callback).Run(std::move(info_mojo_array));
 }
 
+void DlpInternalsPageHandler::ObserveReporting(
+    mojo::PendingRemote<dlp_internals::mojom::ReportingObserver> observer) {
+  reporting_observers_.Add(std::move(observer));
+}
+
+void DlpInternalsPageHandler::OnReportEvent(DlpPolicyEvent event) {
+  dlp_internals::mojom::DlpEventPtr event_mojo =
+      dlp_internals::mojom::DlpEvent::New();
+  if (event.has_source() && event.source().has_url()) {
+    event_mojo->source_pattern = event.source().url();
+  }
+
+  if (event.has_destination()) {
+    event_mojo->destination = EventDestinationToMojo(event.destination());
+  }
+
+  if (event.has_restriction()) {
+    event_mojo->restriction = EventRestrictionToMojo(event.restriction());
+  }
+
+  if (event.mode()) {
+    event_mojo->mode = EventModeToMojo(event.mode());
+  }
+
+  if (event.has_timestamp_micro()) {
+    event_mojo->timestamp_micro = event.timestamp_micro();
+  }
+
+  if (event.has_user_type()) {
+    event_mojo->user_type = EventUserTypeToMojo(event.user_type());
+  }
+
+  if (event.has_content_name()) {
+    event_mojo->content_name = event.content_name();
+  }
+
+  if (event.has_triggered_rule_name()) {
+    event_mojo->triggered_rule_name = event.triggered_rule_name();
+  }
+
+  if (event.has_triggered_rule_id()) {
+    event_mojo->triggered_rule_id = event.triggered_rule_id();
+  }
+
+  for (auto& observer : reporting_observers_) {
+    observer->OnReportEvent(event_mojo.Clone());
+  }
+}
+
 }  // namespace policy
diff --git a/chrome/browser/ui/webui/dlp_internals/dlp_internals_page_handler.h b/chrome/browser/ui/webui/dlp_internals/dlp_internals_page_handler.h
index 463a245..f45f834b 100644
--- a/chrome/browser/ui/webui/dlp_internals/dlp_internals_page_handler.h
+++ b/chrome/browser/ui/webui/dlp_internals/dlp_internals_page_handler.h
@@ -6,16 +6,21 @@
 #define CHROME_BROWSER_UI_WEBUI_DLP_INTERNALS_DLP_INTERNALS_PAGE_HANDLER_H_
 
 #include "base/memory/raw_ptr.h"
+#include "base/scoped_observation.h"
+#include "chrome/browser/enterprise/data_controls/dlp_reporting_manager.h"
 #include "chrome/browser/ui/webui/dlp_internals/dlp_internals.mojom.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/remote_set.h"
 
 class Profile;
 
 namespace policy {
 
 // Concrete implementation of dlp_internals::mojom::PageHandler.
-class DlpInternalsPageHandler : public dlp_internals::mojom::PageHandler {
+class DlpInternalsPageHandler
+    : public dlp_internals::mojom::PageHandler,
+      public data_controls::DlpReportingManager::Observer {
  public:
   DlpInternalsPageHandler(
       mojo::PendingReceiver<dlp_internals::mojom::PageHandler> receiver,
@@ -31,8 +36,20 @@
   void GetClipboardDataSource(GetClipboardDataSourceCallback callback) override;
   void GetContentRestrictionsInfo(
       GetContentRestrictionsInfoCallback callback) override;
+  void ObserveReporting(
+      mojo::PendingRemote<dlp_internals::mojom::ReportingObserver> observer)
+      override;
+
+  // DlpReportingManager::Observer
+  void OnReportEvent(DlpPolicyEvent event) override;
 
   mojo::Receiver<dlp_internals::mojom::PageHandler> receiver_;
+  mojo::RemoteSet<dlp_internals::mojom::ReportingObserver> reporting_observers_;
+
+  base::ScopedObservation<data_controls::DlpReportingManager,
+                          data_controls::DlpReportingManager::Observer>
+      reporting_observation_{this};
+
   raw_ptr<Profile> profile_;
 };
 
diff --git a/chrome/browser/ui/webui/dlp_internals/dlp_internals_ui.cc b/chrome/browser/ui/webui/dlp_internals/dlp_internals_ui.cc
index 103d46e..00809ac 100644
--- a/chrome/browser/ui/webui/dlp_internals/dlp_internals_ui.cc
+++ b/chrome/browser/ui/webui/dlp_internals/dlp_internals_ui.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/webui/dlp_internals/dlp_internals_ui.h"
 
+#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager.h"
 #include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/webui_util.h"
@@ -24,6 +25,9 @@
   DlpRulesManager* rules_manager =
       DlpRulesManagerFactory::GetForPrimaryProfile();
   source->AddBoolean("doRulesManagerExist", rules_manager != nullptr);
+  source->AddBoolean(
+      "isReportingEnabled",
+      rules_manager ? rules_manager->IsReportingEnabled() : false);
 
   webui::SetupWebUIDataSource(
       source,
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_ui.cc b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_ui.cc
index 10d19c4..604d6e9 100644
--- a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_ui.cc
+++ b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_ui.cc
@@ -118,6 +118,8 @@
       {"genericErrorDescription",
        IDS_NTP_WALLPAPER_SEARCH_GENERIC_ERROR_DESCRIPTION},
       {"genericErrorTitle", IDS_NTP_WALLPAPER_SEARCH_GENERIC_ERROR_TITLE},
+      {"offlineDescription", IDS_NTP_WALLPAPER_SEARCH_OFFLINE_DESCRIPTION},
+      {"offlineTitle", IDS_NTP_WALLPAPER_SEARCH_OFFLINE_TITLE},
       {"requestThrottledDescription",
        IDS_NTP_WALLPAPER_SEARCH_REQUEST_THROTTLED_DESCRIPTION},
       {"requestThrottledTitle",
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search.mojom b/chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search.mojom
index 9583591..1976d5d 100644
--- a/chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search.mojom
+++ b/chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search.mojom
@@ -39,6 +39,8 @@
   kError,
   // Too many requests.
   kRequestThrottled,
+  // Browser offline.
+  kOffline,
 };
 
 // Browser-side handler for requests from WebUI page.
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
index ed9616e..6f16712 100644
--- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
+++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
@@ -73,6 +73,7 @@
 #include "third_party/icu/source/i18n/unicode/timezone.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/window_open_disposition.h"
+#include "ui/views/widget/widget.h"
 
 #if BUILDFLAG(IS_MAC)
 #include "chrome/browser/webauthn/chrome_authenticator_request_delegate_mac.h"
@@ -771,13 +772,21 @@
   }
 
 #if BUILDFLAG(IS_MAC)
-  content::WebContents* web_contents =
-      content::WebContents::FromRenderFrameHost(GetRenderFrameHost());
-  BrowserWindow* browser_window =
-      BrowserWindow::FindBrowserWindowWithWebContents(web_contents);
-  if (browser_window) {
-    discovery_factory->set_nswindow(reinterpret_cast<uintptr_t>(
-        browser_window->GetNativeWindow().GetNativeNSWindow()));
+  {
+    content::WebContents* web_contents =
+        content::WebContents::FromRenderFrameHost(GetRenderFrameHost());
+    // Not all contexts in which this code runs have a BrowserWindow.
+    // Notably the dialog containing a WebContents that is used for signing
+    // into a new profile does not. Thus the NSWindow is fetched more directly.
+    const views::Widget* widget = views::Widget::GetTopLevelWidgetForNativeView(
+        web_contents->GetNativeView());
+    if (widget) {
+      const gfx::NativeWindow window = widget->GetNativeWindow();
+      if (window) {
+        discovery_factory->set_nswindow(
+            reinterpret_cast<uintptr_t>(window.GetNativeNSWindow()));
+      }
+    }
   }
 #endif
 
diff --git a/chrome/browser/webauthn/chrome_webauthn_autofill_interactive_uitest.cc b/chrome/browser/webauthn/chrome_webauthn_autofill_interactive_uitest.cc
index b465413..7593f7b 100644
--- a/chrome/browser/webauthn/chrome_webauthn_autofill_interactive_uitest.cc
+++ b/chrome/browser/webauthn/chrome_webauthn_autofill_interactive_uitest.cc
@@ -283,7 +283,7 @@
         << "WebAuthn entry not found";
     EXPECT_EQ(webauthn_entry.main_text.value, u"flandre");
     EXPECT_EQ(webauthn_entry.labels.at(0).at(0).value, GetDeviceString());
-    EXPECT_EQ(webauthn_entry.icon, "globeIcon");
+    EXPECT_EQ(webauthn_entry.icon, autofill::Suggestion::Icon::kGlobe);
 
     // Click the credential.
     popup_controller->AcceptSuggestion(
@@ -330,7 +330,7 @@
         << "WebAuthn entry not found";
     EXPECT_EQ(webauthn_entry.main_text.value, u"flandre");
     EXPECT_EQ(webauthn_entry.labels.at(0).at(0).value, GetDeviceString());
-    EXPECT_EQ(webauthn_entry.icon, "globeIcon");
+    EXPECT_EQ(webauthn_entry.icon, autofill::Suggestion::Icon::kGlobe);
 
     // Abort the request.
     content::ExecuteScriptAsync(web_contents,
@@ -486,7 +486,7 @@
   EXPECT_EQ(webauthn_entry.labels.at(0).at(0).value,
             l10n_util::GetStringFUTF16(IDS_PASSWORD_MANAGER_PASSKEY_FROM_PHONE,
                                        kPhoneName));
-  EXPECT_EQ(webauthn_entry.icon, "globeIcon");
+  EXPECT_EQ(webauthn_entry.icon, autofill::Suggestion::Icon::kGlobe);
 
   // Click the credential.
   popup_controller->AcceptSuggestion(
@@ -564,7 +564,7 @@
   EXPECT_EQ(webauthn_entry->labels.at(0).at(0).value,
             l10n_util::GetStringFUTF16(IDS_PASSWORD_MANAGER_PASSKEY_FROM_PHONE,
                                        kPhoneName));
-  EXPECT_EQ(webauthn_entry->icon, "globeIcon");
+  EXPECT_EQ(webauthn_entry->icon, autofill::Suggestion::Icon::kGlobe);
 
   // Click the credential.
   popup_controller->AcceptSuggestion(
diff --git a/chrome/browser/webauthn/chrome_webauthn_autofill_mac_interactive_uitest.mm b/chrome/browser/webauthn/chrome_webauthn_autofill_mac_interactive_uitest.mm
index 59b884a..16910d46 100644
--- a/chrome/browser/webauthn/chrome_webauthn_autofill_mac_interactive_uitest.mm
+++ b/chrome/browser/webauthn/chrome_webauthn_autofill_mac_interactive_uitest.mm
@@ -136,7 +136,7 @@
   EXPECT_EQ(webauthn_entry.labels.at(0).at(0).value,
             l10n_util::GetStringUTF16(
                 IDS_PASSWORD_MANAGER_PASSKEY_FROM_CHROME_PROFILE));
-  EXPECT_EQ(webauthn_entry.icon, "globeIcon");
+  EXPECT_EQ(webauthn_entry.icon, autofill::Suggestion::Icon::kGlobe);
 
   // Click the credential.
   popup_controller->AcceptSuggestion(
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt
index 8f6f6b2..f4934e16 100644
--- a/chrome/build/android-arm32.pgo.txt
+++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@
-chrome-android32-main-1699293477-4ff17d68ddb72025e317e646b2275ac9fc7c07ed.profdata
+chrome-android32-main-1699336565-c4733d25f424448a37e74f3ddb9d33e6b8f2fba7.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt
index 091b09b..3fb90a9 100644
--- a/chrome/build/android-arm64.pgo.txt
+++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@
-chrome-android64-main-1699293477-b39e0c214d2084d38cde34649d8a18bd11b97855.profdata
+chrome-android64-main-1699336565-343bdb38af694d983872480dcf34865e62981aca.profdata
diff --git a/chrome/build/lacros64.pgo.txt b/chrome/build/lacros64.pgo.txt
index d2bafaf6..ea44404 100644
--- a/chrome/build/lacros64.pgo.txt
+++ b/chrome/build/lacros64.pgo.txt
@@ -1 +1 @@
-chrome-chromeos-amd64-generic-main-1699272180-5cde2f730aee284c1f73d4187cb624d690c2aefd.profdata
+chrome-chromeos-amd64-generic-main-1699315440-fcf36e49ebd6873a373094573916db2ba88391cd.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index a588832e..8a70ea6 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1699293477-803a19a9768f12f214991ceb2c4794345f61f7ac.profdata
+chrome-linux-main-1699336565-5efcaadae5d16d3114a1b067ff924e03a6c4f9d4.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index 5afcf931..8517c3e 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1699307946-8ed71622e381c354d8840b86277ce43e9f67a852.profdata
+chrome-mac-arm-main-1699351053-e75ca465c3b2cf924047d5c359594bd00878a713.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index b4e1d73..2d97148 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1699293477-3ced5de61d2ae45aab086c72fffe81ef7956decf.profdata
+chrome-mac-main-1699336565-b00ef11be4ed41c60f8e1ef2d49b3fa838af3f8e.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt
index 9b8edb6b..3cdcb022 100644
--- a/chrome/build/win-arm64.pgo.txt
+++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@
-chrome-win-arm64-main-1699293477-844945c39a972c3ad4ed2ff319078a56c847d209.profdata
+chrome-win-arm64-main-1699336565-df0bbddd6f71d41d8982b55094ffb2998ae3e579.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 2e1033f6..eb077a5b 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1699293477-b159b1caf91d8ff002a08000a857b9e6e552cff0.profdata
+chrome-win32-main-1699347240-d1ee5980a1f1ebaca1cd0fd888a9c125fc218ae4.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 93886b2..7fc0b3d 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1699282682-29c8298d6af070bce04f66d229218f5cb9310694.profdata
+chrome-win64-main-1699347240-afed11ac3cd69ef29353831e147b13d438221272.profdata
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 2492721..1452a46 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -3355,6 +3355,7 @@
 
     if (enable_dice_support) {
       sources += [
+        "../browser/signin/chrome_signin_client_browsertest.cc",
         "../browser/signin/dice_browsertest.cc",
         "../browser/signin/dice_web_signin_interceptor_browsertest.cc",
         "../browser/signin/signin_ui_util_browsertest.cc",
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py
index 5130ab0..bbfecf1 100755
--- a/chrome/test/chromedriver/test/run_py_tests.py
+++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -121,10 +121,8 @@
     'HeadlessInvalidCertificateTest.testNavigateNewWindow',
     'ChromeDriverTest.testHeadlessWithUserDataDirStarts',
     'ChromeDriverTest.testHeadlessWithExistingUserDataDirStarts',
-    'RemoteBrowserTest.testConnectToRemoteBrowserLiteralAddressHeadless',
     'JavaScriptTests.testAllJS',
     'LaunchDesktopTest.testExistingDevToolsPortFile',
-    'RemoteBrowserTest.testConnectToRemoteBrowser',
     'SessionHandlingTest.testQuitASessionMoreThanOnce',
     'SupportIPv4AndIPv6.testSupportIPv4AndIPv6',
     # Flaky on Win7 bots: crbug.com/1132559
@@ -6235,6 +6233,7 @@
     ports_generator = util.FindProbableFreePorts()
     exception = None
     for _ in range(3):
+      exception = None
       port = next(ports_generator)
       temp_dir = util.MakeTempDir()
       print('temp dir is ' + temp_dir)
@@ -6243,6 +6242,8 @@
              '--user-data-dir=%s' % temp_dir,
              '--use-mock-keychain',
              '--password-store=basic']
+      if _BROWSER_NAME == 'chrome-headless-shell':
+        cmd.append('data:,')
       process = subprocess.Popen(cmd)
       try:
         driver = self.CreateDriver(debugger_address='localhost:%d' % port)
@@ -6250,7 +6251,9 @@
         driver.Quit()
       except Exception as e:
         exception = e
-        continue
+
+      # The process must be closed on each iteration otherwise a resource leak
+      # happens.
       if process.poll() is None:
         process.terminate()
         # Wait for Chrome to exit here to prevent a race with Chrome to
@@ -6277,6 +6280,7 @@
       ports_generator = util.FindProbableFreePorts()
       exception = None
       for _ in range(3):
+        exception = None
         port = next(ports_generator)
         temp_dir = util.MakeTempDir()
         print('temp dir is ' + temp_dir)
@@ -6297,7 +6301,9 @@
           driver.Quit()
         except Exception as e:
           exception = e
-          continue
+
+        # The process must be closed on each iteration otherwise a resource leak
+        # happens.
         if process.poll() is None:
           process.terminate()
           # Wait for Chrome to exit here to prevent a race with Chrome to
diff --git a/chrome/test/data/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_test.ts b/chrome/test/data/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_test.ts
index 0db42fd..4d66fe28 100644
--- a/chrome/test/data/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_test.ts
+++ b/chrome/test/data/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_test.ts
@@ -10,6 +10,7 @@
 import {Descriptors, WallpaperSearchHandlerInterface, WallpaperSearchHandlerRemote, WallpaperSearchStatus} from 'chrome://customize-chrome-side-panel.top-chrome/wallpaper_search.mojom-webui.js';
 import {DESCRIPTOR_D_VALUE, WallpaperSearchElement} from 'chrome://customize-chrome-side-panel.top-chrome/wallpaper_search/wallpaper_search.js';
 import {WallpaperSearchProxy} from 'chrome://customize-chrome-side-panel.top-chrome/wallpaper_search/wallpaper_search_proxy.js';
+import {WindowProxy} from 'chrome://customize-chrome-side-panel.top-chrome/window_proxy.js';
 import {hexColorToSkColor} from 'chrome://resources/js/color_utils.js';
 import {PromiseResolver} from 'chrome://resources/js/promise_resolver.js';
 import {assertDeepEquals, assertEquals, assertFalse, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
@@ -23,6 +24,7 @@
   let callbackRouterRemote: CustomizeChromePageRemote;
   let handler: TestMock<WallpaperSearchHandlerInterface>;
   let wallpaperSearchElement: WallpaperSearchElement;
+  let windowProxy: TestMock<WindowProxy>;
 
   async function createWallpaperSearchElement(
       descriptors: Descriptors|null = null): Promise<WallpaperSearchElement> {
@@ -43,6 +45,8 @@
 
   setup(async () => {
     document.body.innerHTML = window.trustedTypes!.emptyHTML;
+    windowProxy = installMock(WindowProxy);
+    windowProxy.setResultFor('onLine', true);
     handler = installMock(
         WallpaperSearchHandlerRemote,
         (mock: WallpaperSearchHandlerInterface) =>
@@ -484,6 +488,40 @@
           $$(wallpaperSearchElement, '#wallpaperSearch')!, 'display', 'none');
     });
 
+    test('shows error ui if browser if offline', async () => {
+      windowProxy.setResultFor('onLine', false);
+      createWallpaperSearchElementWithDescriptors();
+      await flushTasks();
+
+      wallpaperSearchElement.$.submitButton.click();
+      await waitAfterNextRender(wallpaperSearchElement);
+
+      assertEquals(1, windowProxy.getCallCount('onLine'));
+      assertNotStyle($$(wallpaperSearchElement, '#error')!, 'display', 'none');
+      assertStyle(
+          $$(wallpaperSearchElement, '#wallpaperSearch')!, 'display', 'none');
+    });
+
+    test('checks if browser is back online', async () => {
+      windowProxy.setResultFor('onLine', false);
+      createWallpaperSearchElementWithDescriptors();
+      await flushTasks();
+
+      wallpaperSearchElement.$.submitButton.click();
+      await waitAfterNextRender(wallpaperSearchElement);
+
+      assertEquals(1, windowProxy.getCallCount('onLine'));
+      windowProxy.setResultFor('onLine', true);
+
+      $$<HTMLElement>(wallpaperSearchElement, '#errorCTA')!.click();
+      await waitAfterNextRender(wallpaperSearchElement);
+
+      assertEquals(2, windowProxy.getCallCount('onLine'));
+      assertStyle($$(wallpaperSearchElement, '#error')!, 'display', 'none');
+      assertNotStyle(
+          $$(wallpaperSearchElement, '#wallpaperSearch')!, 'display', 'none');
+    });
+
     test('shows search ui if there are no errors', async () => {
       handler.setResultFor(
           'getWallpaperSearchResults',
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index e46b4b81..8844772b 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-15669.0.0
\ No newline at end of file
+15670.0.0
\ No newline at end of file
diff --git a/chromeos/ash/components/audio/cras_audio_handler.cc b/chromeos/ash/components/audio/cras_audio_handler.cc
index 209cd2a..09f668e 100644
--- a/chromeos/ash/components/audio/cras_audio_handler.cc
+++ b/chromeos/ash/components/audio/cras_audio_handler.cc
@@ -1402,9 +1402,6 @@
 AudioDevice CrasAudioHandler::ConvertAudioNodeWithModifiedPriority(
     const AudioNode& node) {
   AudioDevice device(node);
-  if (deprioritize_bt_wbs_mic_ && device.is_input &&
-      (device.type == AudioDeviceType::kBluetooth))
-    device.priority = 0;
 
   if (base::FeatureList::IsEnabled(features::kRobustAudioDeviceSelectLogic))
     device.user_priority = audio_pref_handler_->GetUserPriority(device);
@@ -1544,16 +1541,6 @@
   CrasAudioClient::Get()->SetFixA2dpPacketSize(
       base::FeatureList::IsEnabled(features::kBluetoothFixA2dpPacketSize));
 
-  // When the BluetoothWbsDogfood feature flag is enabled, don't bother
-  // calling GetDeprioritizeBtWbsMic().
-  // Otherwise override the Bluetooth WBS mic's priority according to the
-  // |deprioritize_bt_wbs_mic| value returned by CRAS.
-  if (!base::FeatureList::IsEnabled(features::kBluetoothWbsDogfood)) {
-    CrasAudioClient::Get()->GetDeprioritizeBtWbsMic(
-        base::BindOnce(&CrasAudioHandler::HandleGetDeprioritizeBtWbsMic,
-                       weak_ptr_factory_.GetWeakPtr()));
-  }
-
   // Sets Floss enabled based on feature flag.
   CrasAudioClient::Get()->SetFlossEnabled(floss::features::IsFlossEnabled());
 
@@ -2287,15 +2274,6 @@
   num_active_output_streams_ = *new_output_streams_count;
 }
 
-void CrasAudioHandler::HandleGetDeprioritizeBtWbsMic(
-    absl::optional<bool> deprioritize_bt_wbs_mic) {
-  if (!deprioritize_bt_wbs_mic.has_value()) {
-    LOG(ERROR) << "Failed to retrieve WBS mic deprioritized flag";
-    return;
-  }
-  deprioritize_bt_wbs_mic_ = *deprioritize_bt_wbs_mic;
-}
-
 void CrasAudioHandler::AddAdditionalActiveNode(uint64_t node_id, bool notify) {
   const AudioDevice* device = GetDeviceFromId(node_id);
   if (!device) {
diff --git a/chromeos/ash/components/audio/cras_audio_handler.h b/chromeos/ash/components/audio/cras_audio_handler.h
index 9f074eb..5950b5c 100644
--- a/chromeos/ash/components/audio/cras_audio_handler.h
+++ b/chromeos/ash/components/audio/cras_audio_handler.h
@@ -757,9 +757,6 @@
   void HandleGetNumActiveOutputStreams(
       absl::optional<int> num_active_output_streams);
 
-  void HandleGetDeprioritizeBtWbsMic(
-      absl::optional<bool> deprioritize_bt_wbs_mic);
-
   // Adds an active node.
   // If there is no active node, |node_id| will be switched to become the
   // primary active node. Otherwise, it will be added as an additional active
@@ -1004,11 +1001,6 @@
 
   bool fetch_media_session_duration_ = false;
 
-  // On a few platforms that Bluetooth WBS is still working to be
-  // stabilized, CRAS may report to deprioritze the BT WBS mic's node
-  // priority.
-  bool deprioritize_bt_wbs_mic_ = false;
-
   // Whether the audio input is muted because the microphone mute switch is on.
   // In this case, input mute changes will be disabled.
   bool input_muted_by_microphone_mute_switch_ = false;
diff --git a/chromeos/ash/components/dbus/audio/cras_audio_client.cc b/chromeos/ash/components/dbus/audio/cras_audio_client.cc
index 53bbb71..4620aab 100644
--- a/chromeos/ash/components/dbus/audio/cras_audio_client.cc
+++ b/chromeos/ash/components/dbus/audio/cras_audio_client.cc
@@ -282,16 +282,6 @@
             weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
   }
 
-  void GetDeprioritizeBtWbsMic(
-      chromeos::DBusMethodCallback<bool> callback) override {
-    dbus::MethodCall method_call(cras::kCrasControlInterface,
-                                 cras::kGetDeprioritizeBtWbsMic);
-    cras_proxy_->CallMethod(
-        &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::BindOnce(&CrasAudioClientImpl::OnGetDeprioritizeBtWbsMic,
-                       weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
-  }
-
   void GetNumberOfNonChromeOutputStreams(
       chromeos::DBusMethodCallback<int32_t> callback) override {
     dbus::MethodCall method_call(cras::kCrasControlInterface,
@@ -1148,25 +1138,6 @@
     std::move(callback).Run(std::move(res));
   }
 
-  void OnGetDeprioritizeBtWbsMic(chromeos::DBusMethodCallback<bool> callback,
-                                 dbus::Response* response) {
-    if (!response) {
-      LOG(ERROR) << "Error calling "
-                 << "GetDeprioritizeBtWbsMic";
-      std::move(callback).Run(absl::nullopt);
-      return;
-    }
-    bool deprioritize_bt_wbs_mic = 0;
-    dbus::MessageReader reader(response);
-    if (!reader.PopBool(&deprioritize_bt_wbs_mic)) {
-      LOG(ERROR) << "Error reading response from cras: "
-                 << response->ToString();
-      std::move(callback).Run(absl::nullopt);
-      return;
-    }
-    std::move(callback).Run(deprioritize_bt_wbs_mic);
-  }
-
   void OnSetHotwordModel(chromeos::VoidDBusMethodCallback callback,
                          dbus::Response* response) {
     if (!response) {
diff --git a/chromeos/ash/components/dbus/audio/cras_audio_client.h b/chromeos/ash/components/dbus/audio/cras_audio_client.h
index 11f21c6..a1c3be9 100644
--- a/chromeos/ash/components/dbus/audio/cras_audio_client.h
+++ b/chromeos/ash/components/dbus/audio/cras_audio_client.h
@@ -153,12 +153,6 @@
   virtual void GetNumberOfInputStreamsWithPermission(
       chromeos::DBusMethodCallback<base::flat_map<std::string, uint32_t>>) = 0;
 
-  // Gets the DeprioritzeBtWbsMic flag. On a few platforms CRAS may
-  // report to deprioritize Bluetooth WBS mic's node priority because
-  // WBS feature is still working to be stabilized.
-  virtual void GetDeprioritizeBtWbsMic(
-      chromeos::DBusMethodCallback<bool> callback) = 0;
-
   // Get the number of active non-chrome output streams.
   virtual void GetNumberOfNonChromeOutputStreams(
       chromeos::DBusMethodCallback<int32_t> callback) = 0;
diff --git a/chromeos/ash/components/dbus/audio/fake_cras_audio_client.cc b/chromeos/ash/components/dbus/audio/fake_cras_audio_client.cc
index 86e509c0..48196a6 100644
--- a/chromeos/ash/components/dbus/audio/fake_cras_audio_client.cc
+++ b/chromeos/ash/components/dbus/audio/fake_cras_audio_client.cc
@@ -193,11 +193,6 @@
   std::move(callback).Run(active_input_streams_);
 }
 
-void FakeCrasAudioClient::GetDeprioritizeBtWbsMic(
-    chromeos::DBusMethodCallback<bool> callback) {
-  std::move(callback).Run(false);
-}
-
 void FakeCrasAudioClient::GetSpeakOnMuteDetectionEnabled(
     chromeos::DBusMethodCallback<bool> callback) {
   std::move(callback).Run(false);
diff --git a/chromeos/ash/components/dbus/audio/fake_cras_audio_client.h b/chromeos/ash/components/dbus/audio/fake_cras_audio_client.h
index f24f66c..bff4f42 100644
--- a/chromeos/ash/components/dbus/audio/fake_cras_audio_client.h
+++ b/chromeos/ash/components/dbus/audio/fake_cras_audio_client.h
@@ -59,8 +59,6 @@
       chromeos::DBusMethodCallback<int> callback) override;
   void GetNumberOfInputStreamsWithPermission(
       chromeos::DBusMethodCallback<ClientTypeToInputStreamCount>) override;
-  void GetDeprioritizeBtWbsMic(
-      chromeos::DBusMethodCallback<bool> callback) override;
   void GetSpeakOnMuteDetectionEnabled(
       chromeos::DBusMethodCallback<bool> callback) override;
   void SetOutputNodeVolume(uint64_t node_id, int32_t volume) override;
diff --git a/chromeos/ash/components/drivefs/drivefs_pinning_manager.cc b/chromeos/ash/components/drivefs/drivefs_pinning_manager.cc
index ece4aef..dc087dc 100644
--- a/chromeos/ash/components/drivefs/drivefs_pinning_manager.cc
+++ b/chromeos/ash/components/drivefs/drivefs_pinning_manager.cc
@@ -682,6 +682,7 @@
 }
 
 PinningManager::~PinningManager() {
+  Stop();
   VLOG(1) << "Deleting bulk-pinning manager";
 }
 
diff --git a/chromeos/ash/components/settings/cros_settings_names.cc b/chromeos/ash/components/settings/cros_settings_names.cc
index d553703..bea5303 100644
--- a/chromeos/ash/components/settings/cros_settings_names.cc
+++ b/chromeos/ash/components/settings/cros_settings_names.cc
@@ -312,11 +312,6 @@
 const char kVariationsRestrictParameter[] =
     "cros.variations_restrict_parameter";
 
-// TODO(b/285556135): Remove this pref together with AttestationEnabledForDevice
-// A boolean pref that indicates whether enterprise attestation is enabled for
-// the device.
-const char kDeviceAttestationEnabled[] = "cros.device.attestation_enabled";
-
 // A boolean pref that indicates whether attestation for content protection is
 // enabled for the device.
 const char kAttestationForContentProtectionEnabled[] =
diff --git a/chromeos/ash/components/settings/cros_settings_names.h b/chromeos/ash/components/settings/cros_settings_names.h
index 9d36f78..7843dae 100644
--- a/chromeos/ash/components/settings/cros_settings_names.h
+++ b/chromeos/ash/components/settings/cros_settings_names.h
@@ -212,8 +212,6 @@
 extern const char kVariationsRestrictParameter[];
 
 COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_SETTINGS)
-extern const char kDeviceAttestationEnabled[];
-COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_SETTINGS)
 extern const char kAttestationForContentProtectionEnabled[];
 
 COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_SETTINGS)
diff --git a/chromeos/components/in_session_auth/mojom/BUILD.gn b/chromeos/components/in_session_auth/mojom/BUILD.gn
new file mode 100644
index 0000000..704f1e9
--- /dev/null
+++ b/chromeos/components/in_session_auth/mojom/BUILD.gn
@@ -0,0 +1,15 @@
+# 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.
+
+import("//build/config/chromeos/ui_mode.gni")
+import("//mojo/public/tools/bindings/mojom.gni")
+
+mojom("mojom") {
+  sources = [ "in_session_auth.mojom" ]
+  webui_module_path =
+      "chrome://resources/mojo/chromeos/components/in_session_auth/mojom"
+  use_typescript_sources = true
+
+  public_deps = [ "//mojo/public/mojom/base" ]
+}
diff --git a/chromeos/components/in_session_auth/mojom/OWNERS b/chromeos/components/in_session_auth/mojom/OWNERS
new file mode 100644
index 0000000..08850f4
--- /dev/null
+++ b/chromeos/components/in_session_auth/mojom/OWNERS
@@ -0,0 +1,2 @@
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromeos/crosapi/mojom/in_session_auth.mojom b/chromeos/components/in_session_auth/mojom/in_session_auth.mojom
similarity index 62%
rename from chromeos/crosapi/mojom/in_session_auth.mojom
rename to chromeos/components/in_session_auth/mojom/in_session_auth.mojom
index 960a7d4f6..fa16e53 100644
--- a/chromeos/crosapi/mojom/in_session_auth.mojom
+++ b/chromeos/components/in_session_auth/mojom/in_session_auth.mojom
@@ -1,12 +1,20 @@
-// Copyright 2022 The Chromium Authors
+// 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.
 
-module crosapi.mojom;
+// This module serves as an interface for requesting, validating,
+// and invalidated authentication tokens for various sensitive OS
+// settings operations, such as modifying lock screen settings.
+// This module is also used from lacros to authenticate users
+// in password manager scenarios.
+// The aquired token is perishable, and can be reused for as long
+// as it is valid. Token are managed by ash's `AuthSessionStorage`.
+
+module chromeos.auth.mojom;
 
 import "mojo/public/mojom/base/time.mojom";
 
-[Stable]
+[Stable, RenamedFrom="crosapi.mojom.RequestTokenReply"]
 struct RequestTokenReply {
   // The authentication token that is returned, to use for sensitive
   // operations.
@@ -16,7 +24,7 @@
   mojo_base.mojom.TimeDelta timeout@1;
 };
 
-[Stable, Extensible]
+[Stable, Extensible, RenamedFrom="crosapi.mojom.Reason"]
 enum Reason {
   [Default] kAccessPasswordManager = 0,
   kModifyAuthFactors,
@@ -24,8 +32,8 @@
 };
 
 // An interface implemented by Ash to expose Ash's authentication capabilities.
-// Used by Lacros for extension API authentication in Settings.
-[Stable, Uuid="7d4bb0d8-f1fa-46bf-a7a6-b7117526ea63"]
+[Stable, Uuid="7d4bb0d8-f1fa-46bf-a7a6-b7117526ea63",
+  RenamedFrom="crosapi.mojom.InSessionAuth"]
 interface InSessionAuth {
   // Instructs Ash to summon a native authentication dialog to authenticate
   // the currently active user. Returns a prerishable authentication token on
diff --git a/chromeos/crosapi/mojom/BUILD.gn b/chromeos/crosapi/mojom/BUILD.gn
index e867295..6924242 100644
--- a/chromeos/crosapi/mojom/BUILD.gn
+++ b/chromeos/crosapi/mojom/BUILD.gn
@@ -61,7 +61,6 @@
     "identity_manager.mojom",
     "idle_service.mojom",
     "image_writer.mojom",
-    "in_session_auth.mojom",
     "kerberos_in_browser.mojom",
     "keystore_error.mojom",
     "keystore_service.mojom",
@@ -131,6 +130,7 @@
   public_deps = [
     ":video_capture",
     "//chromeos/components/drivefs/mojom",
+    "//chromeos/components/in_session_auth/mojom",
     "//chromeos/components/payments/mojom",
     "//chromeos/components/remote_apps/mojom",
     "//chromeos/components/sensors/mojom",
diff --git a/chromeos/crosapi/mojom/crosapi.mojom b/chromeos/crosapi/mojom/crosapi.mojom
index 57e058f..351ae31 100644
--- a/chromeos/crosapi/mojom/crosapi.mojom
+++ b/chromeos/crosapi/mojom/crosapi.mojom
@@ -4,6 +4,7 @@
 
 module crosapi.mojom;
 
+import "chromeos/components/in_session_auth/mojom/in_session_auth.mojom";
 import "chromeos/components/payments/mojom/payment_app.mojom";
 import "chromeos/components/remote_apps/mojom/remote_apps.mojom";
 import "chromeos/components/sensors/mojom/cros_sensor_service.mojom";
@@ -57,7 +58,6 @@
 import "chromeos/crosapi/mojom/identity_manager.mojom";
 import "chromeos/crosapi/mojom/idle_service.mojom";
 import "chromeos/crosapi/mojom/image_writer.mojom";
-import "chromeos/crosapi/mojom/in_session_auth.mojom";
 import "chromeos/crosapi/mojom/kerberos_in_browser.mojom";
 import "chromeos/crosapi/mojom/keystore_service.mojom";
 import "chromeos/crosapi/mojom/launcher_search.mojom";
@@ -437,7 +437,8 @@
   // on ChromeOS
   // Added in M106.
   [MinVersion=92]
-  BindInSessionAuth@96(pending_receiver<InSessionAuth> receiver);
+  BindInSessionAuth@96(
+      pending_receiver<chromeos.auth.mojom.InSessionAuth> receiver);
 
   // Binds the NetworkSettingsService interface for reading and observing
   // network changes.
diff --git a/chromeos/lacros/lacros_service.cc b/chromeos/lacros/lacros_service.cc
index c55fcc4..ae90e50 100644
--- a/chromeos/lacros/lacros_service.cc
+++ b/chromeos/lacros/lacros_service.cc
@@ -16,6 +16,7 @@
 #include "base/task/thread_pool.h"
 #include "build/chromeos_buildflags.h"
 #include "chromeos/components/cdm_factory_daemon/mojom/browser_cdm_factory.mojom.h"
+#include "chromeos/components/in_session_auth/mojom/in_session_auth.mojom.h"
 #include "chromeos/components/payments/mojom/payment_app.mojom.h"
 #include "chromeos/components/remote_apps/mojom/remote_apps.mojom.h"
 #include "chromeos/constants/chromeos_features.h"
@@ -68,7 +69,6 @@
 #include "chromeos/crosapi/mojom/holding_space_service.mojom.h"
 #include "chromeos/crosapi/mojom/identity_manager.mojom.h"
 #include "chromeos/crosapi/mojom/image_writer.mojom.h"
-#include "chromeos/crosapi/mojom/in_session_auth.mojom.h"
 #include "chromeos/crosapi/mojom/kerberos_in_browser.mojom.h"
 #include "chromeos/crosapi/mojom/keystore_service.mojom.h"
 #include "chromeos/crosapi/mojom/kiosk_session_service.mojom.h"
@@ -414,7 +414,7 @@
   ConstructRemote<crosapi::mojom::ImageWriter,
                   &crosapi::mojom::Crosapi::BindImageWriter,
                   Crosapi::MethodMinVersions::kBindImageWriterMinVersion>();
-  ConstructRemote<crosapi::mojom::InSessionAuth,
+  ConstructRemote<chromeos::auth::mojom::InSessionAuth,
                   &crosapi::mojom::Crosapi::BindInSessionAuth,
                   Crosapi::MethodMinVersions::kBindInSessionAuthMinVersion>();
   ConstructRemote<
diff --git a/chromeos/profiles/arm-exp.afdo.newest.txt b/chromeos/profiles/arm-exp.afdo.newest.txt
index 1e7b410..212c9b1 100644
--- a/chromeos/profiles/arm-exp.afdo.newest.txt
+++ b/chromeos/profiles/arm-exp.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-arm-exp-120-6085.0-1698659522-benchmark-121.0.6109.0-r1-redacted.afdo.xz
+chromeos-chrome-arm-exp-121-6085.0-1699270938-benchmark-121.0.6109.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/arm.afdo.newest.txt b/chromeos/profiles/arm.afdo.newest.txt
index d48d21df..4f36bc6e 100644
--- a/chromeos/profiles/arm.afdo.newest.txt
+++ b/chromeos/profiles/arm.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-arm-none-120-6045.38-1698665925-benchmark-121.0.6109.0-r1-redacted.afdo.xz
+chromeos-chrome-arm-none-121-6085.0-1699275463-benchmark-121.0.6110.0-r1-redacted.afdo.xz
diff --git a/chromeos/profiles/atom.afdo.newest.txt b/chromeos/profiles/atom.afdo.newest.txt
index 7ec76c7..fa493586 100644
--- a/chromeos/profiles/atom.afdo.newest.txt
+++ b/chromeos/profiles/atom.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-atom-120-6085.0-1698659522-benchmark-121.0.6109.0-r1-redacted.afdo.xz
+chromeos-chrome-amd64-atom-121-6085.0-1699270938-benchmark-121.0.6110.0-r1-redacted.afdo.xz
diff --git a/clank b/clank
index c000cb7..4cee13a 160000
--- a/clank
+++ b/clank
@@ -1 +1 @@
-Subproject commit c000cb71605baf6bfb5e5bcc6765491ccedc7369
+Subproject commit 4cee13aad60c25a716fcf4015117580851516cb9
diff --git a/components/attribution_reporting/os_registration.h b/components/attribution_reporting/os_registration.h
index 179dbbf..06f2b0e 100644
--- a/components/attribution_reporting/os_registration.h
+++ b/components/attribution_reporting/os_registration.h
@@ -8,7 +8,7 @@
 #include <vector>
 
 #include "base/component_export.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "net/http/structured_headers.h"
 #include "url/gurl.h"
 
diff --git a/components/attribution_reporting/parsing_utils.h b/components/attribution_reporting/parsing_utils.h
index 2526009c..3106ac1 100644
--- a/components/attribution_reporting/parsing_utils.h
+++ b/components/attribution_reporting/parsing_utils.h
@@ -10,7 +10,7 @@
 #include <string>
 
 #include "base/component_export.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/types/expected.h"
 #include "base/values.h"
 #include "components/attribution_reporting/source_registration_error.mojom-forward.h"
diff --git a/components/attribution_reporting/source_registration.h b/components/attribution_reporting/source_registration.h
index a9be7fa..5128db6 100644
--- a/components/attribution_reporting/source_registration.h
+++ b/components/attribution_reporting/source_registration.h
@@ -8,7 +8,7 @@
 #include <stdint.h>
 
 #include "base/component_export.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "base/types/expected.h"
 #include "base/values.h"
diff --git a/components/attribution_reporting/suitable_origin.h b/components/attribution_reporting/suitable_origin.h
index fb441901..a0dffbc 100644
--- a/components/attribution_reporting/suitable_origin.h
+++ b/components/attribution_reporting/suitable_origin.h
@@ -10,7 +10,7 @@
 
 #include "base/check.h"
 #include "base/component_export.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "mojo/public/cpp/bindings/default_construct_tag.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/origin.h"
diff --git a/components/attribution_reporting/trigger_registration.h b/components/attribution_reporting/trigger_registration.h
index a253e4f..071c251 100644
--- a/components/attribution_reporting/trigger_registration.h
+++ b/components/attribution_reporting/trigger_registration.h
@@ -10,7 +10,7 @@
 #include <vector>
 
 #include "base/component_export.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/types/expected.h"
 #include "base/values.h"
 #include "components/attribution_reporting/aggregatable_values.h"
diff --git a/components/autofill/android/BUILD.gn b/components/autofill/android/BUILD.gn
index 851b162..78cd942 100644
--- a/components/autofill/android/BUILD.gn
+++ b/components/autofill/android/BUILD.gn
@@ -143,6 +143,7 @@
     "../core/browser/ui/accessory_sheet_enums.h",
     "../core/browser/ui/payments/payments_bubble_closed_reasons.h",
     "../core/browser/ui/popup_item_ids.h",
+    "../core/browser/ui/suggestion.h",
   ]
 }
 
diff --git a/components/autofill/core/browser/autofill_data_util.h b/components/autofill/core/browser/autofill_data_util.h
index 2325a3d0..2b61846 100644
--- a/components/autofill/core/browser/autofill_data_util.h
+++ b/components/autofill/core/browser/autofill_data_util.h
@@ -8,7 +8,7 @@
 #include <string>
 #include <vector>
 
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "components/autofill/core/browser/field_types.h"
 
 namespace autofill {
diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc
index 0813f18..cd69806 100644
--- a/components/autofill/core/browser/autofill_external_delegate.cc
+++ b/components/autofill/core/browser/autofill_external_delegate.cc
@@ -218,7 +218,7 @@
     Suggestion scan_credit_card(
         l10n_util::GetStringUTF16(IDS_AUTOFILL_SCAN_CREDIT_CARD));
     scan_credit_card.popup_item_id = PopupItemId::kScanCreditCard;
-    scan_credit_card.icon = "scanCreditCardIcon";
+    scan_credit_card.icon = Suggestion::Icon::kScanCreditCard;
     suggestions.push_back(scan_credit_card);
   }
 
@@ -226,7 +226,7 @@
     suggestions.emplace_back(
         l10n_util::GetStringUTF16(IDS_AUTOFILL_SHOW_ACCOUNT_CARDS));
     suggestions.back().popup_item_id = PopupItemId::kShowAccountCards;
-    suggestions.back().icon = "google";
+    suggestions.back().icon = Suggestion::Icon::kGoogle;
   }
 
   if (has_autofill_suggestions_)
@@ -458,6 +458,8 @@
     case PopupItemId::kFieldByFieldFilling:
       if (const AutofillField* autofill_trigger_field =
               GetQueriedAutofillField()) {
+        LogFillingMethodUsed(autofill_metrics::AutofillFillingMethodMetric::
+                                 kFieldByFieldFilling);
         // We target only the triggering field type in the
         // PopupItemId::kFieldByFieldFilling case.
         last_field_types_to_fill_for_address_form_section_
@@ -482,6 +484,8 @@
                                                 query_form_, query_field_);
       break;
     case PopupItemId::kFillFullAddress:
+      LogFillingMethodUsed(
+          autofill_metrics::AutofillFillingMethodMetric::kGroupFillingAddress);
       FillAutofillFormData(
           suggestion.popup_item_id,
           suggestion.GetPayload<Suggestion::BackendId>(), /*is_preview=*/false,
@@ -490,6 +494,8 @@
            .field_types_to_fill = GetAddressFieldsForGroupFilling()});
       break;
     case PopupItemId::kFillFullName:
+      LogFillingMethodUsed(
+          autofill_metrics::AutofillFillingMethodMetric::kGroupFillingName);
       FillAutofillFormData(
           suggestion.popup_item_id,
           suggestion.GetPayload<Suggestion::BackendId>(), /*is_preview=*/false,
@@ -499,6 +505,8 @@
                GetServerFieldTypesOfGroup(FieldTypeGroup::kName)});
       break;
     case PopupItemId::kFillFullPhoneNumber:
+      LogFillingMethodUsed(autofill_metrics::AutofillFillingMethodMetric::
+                               kGroupFillingPhoneNumber);
       FillAutofillFormData(
           suggestion.popup_item_id,
           suggestion.GetPayload<Suggestion::BackendId>(), /*is_preview=*/false,
@@ -508,6 +516,8 @@
                GetServerFieldTypesOfGroup(FieldTypeGroup::kPhone)});
       break;
     case PopupItemId::kFillFullEmail:
+      LogFillingMethodUsed(
+          autofill_metrics::AutofillFillingMethodMetric::kGroupFillingEmail);
       FillAutofillFormData(
           suggestion.popup_item_id,
           suggestion.GetPayload<Suggestion::BackendId>(), /*is_preview=*/false,
@@ -609,6 +619,12 @@
               PopupItemId::kFillEverythingFromAddressProfile) {
         autofill_metrics::LogAutofillSuggestionAcceptedIndex(
             position, popup_type_, manager_->client().IsOffTheRecord());
+        if (suggestion.popup_item_id == PopupItemId::kAddressEntry ||
+            suggestion.popup_item_id ==
+                PopupItemId::kFillEverythingFromAddressProfile) {
+          LogFillingMethodUsed(
+              autofill_metrics::AutofillFillingMethodMetric::kFullForm);
+        }
       }
       if (suggestion.popup_item_id == PopupItemId::kAddressEntry &&
           manager_->WasSuggestionPreviouslyHidden(
@@ -865,8 +881,9 @@
     suggestions->emplace_back(value);
     suggestions->back().popup_item_id = PopupItemId::kClearForm;
     suggestions->back().icon =
-        base::FeatureList::IsEnabled(features::kAutofillUndo) ? "undoIcon"
-                                                              : "clearIcon";
+        base::FeatureList::IsEnabled(features::kAutofillUndo)
+            ? Suggestion::Icon::kUndo
+            : Suggestion::Icon::kClear;
     suggestions->back().acceptance_a11y_announcement =
         l10n_util::GetStringUTF16(IDS_AUTOFILL_A11Y_ANNOUNCE_CLEARED_FORM);
   }
@@ -875,18 +892,18 @@
   // popup layout experiment.
   suggestions->emplace_back(GetSettingsSuggestionValue());
   suggestions->back().popup_item_id = PopupItemId::kAutofillOptions;
-  suggestions->back().icon = "settingsIcon";
+  suggestions->back().icon = Suggestion::Icon::kSettings;
 
   // On Android and Desktop, Google Pay branding is shown along with Settings.
   // So Google Pay Icon is just attached to an existing menu item.
   if (is_all_server_suggestions) {
 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
-    suggestions->back().icon = "googlePay";
+    suggestions->back().icon = Suggestion::Icon::kGooglePay;
 #else
     suggestions->back().trailing_icon =
         ui::NativeTheme::GetInstanceForNativeUi()->ShouldUseDarkColors()
-            ? "googlePayDark"
-            : "googlePay";
+            ? Suggestion::Icon::kGooglePayDark
+            : Suggestion::Icon::kGooglePay;
 #endif
   }
 }
diff --git a/components/autofill/core/browser/autofill_external_delegate_unittest.cc b/components/autofill/core/browser/autofill_external_delegate_unittest.cc
index c0a80df2..9f8dd5fa 100644
--- a/components/autofill/core/browser/autofill_external_delegate_unittest.cc
+++ b/components/autofill/core/browser/autofill_external_delegate_unittest.cc
@@ -28,6 +28,7 @@
 #include "components/autofill/core/browser/browser_autofill_manager.h"
 #include "components/autofill/core/browser/data_model/autofill_profile.h"
 #include "components/autofill/core/browser/metrics/autofill_metrics.h"
+#include "components/autofill/core/browser/metrics/granular_filling_metrics.h"
 #include "components/autofill/core/browser/metrics/log_event.h"
 #include "components/autofill/core/browser/mock_autofill_compose_delegate.h"
 #include "components/autofill/core/browser/personal_data_manager_observer.h"
@@ -61,6 +62,7 @@
 
 using ::testing::_;
 using ::testing::AllOf;
+using ::testing::AnyOf;
 using ::testing::ElementsAre;
 using ::testing::Field;
 using ::testing::Matcher;
@@ -1069,6 +1071,72 @@
       /*position=*/0, kDefaultTriggerSource);
 }
 
+// Test parameter data for asserting filling method metrics depending on the
+// suggestion (`PopupItemId`) accepted.
+struct FillingMethodMetricsTestParams {
+  const PopupItemId popup_item_id;
+  const autofill_metrics::AutofillFillingMethodMetric target_metric;
+  const std::string test_name;
+};
+
+class FillingMethodMetricsUnitTest
+    : public AutofillExternalDelegateUnitTest,
+      public ::testing::WithParamInterface<FillingMethodMetricsTestParams> {};
+
+const FillingMethodMetricsTestParams kFillingMethodMetricsTestCases[] = {
+    {.popup_item_id = PopupItemId::kAddressEntry,
+     .target_metric = autofill_metrics::AutofillFillingMethodMetric::kFullForm,
+     .test_name = "addressEntry"},
+    {.popup_item_id = PopupItemId::kFillEverythingFromAddressProfile,
+     .target_metric = autofill_metrics::AutofillFillingMethodMetric::kFullForm,
+     .test_name = "fillEveythingFromAddressProfile"},
+    {.popup_item_id = PopupItemId::kFieldByFieldFilling,
+     .target_metric =
+         autofill_metrics::AutofillFillingMethodMetric::kFieldByFieldFilling,
+     .test_name = "fieldByFieldFilling"},
+    {.popup_item_id = PopupItemId::kFillFullAddress,
+     .target_metric =
+         autofill_metrics::AutofillFillingMethodMetric::kGroupFillingAddress,
+     .test_name = "fillFullAddress"},
+    {.popup_item_id = PopupItemId::kFillFullPhoneNumber,
+     .target_metric = autofill_metrics::AutofillFillingMethodMetric::
+         kGroupFillingPhoneNumber,
+     .test_name = "fillFullPhoneNumber"},
+    {.popup_item_id = PopupItemId::kFillFullEmail,
+     .target_metric =
+         autofill_metrics::AutofillFillingMethodMetric::kGroupFillingEmail,
+     .test_name = "fillFullEmail"},
+};
+
+// Tests that for a certain `PopupItemId` accepted, the expected
+// `AutofillFillingMethodMetric` is recorded.
+TEST_P(FillingMethodMetricsUnitTest, recordedsFillingMethodForPopupType) {
+  IssueOnQuery();
+  const FillingMethodMetricsTestParams& params = GetParam();
+  const AutofillProfile profile = test::GetFullProfile();
+  personal_data().AddProfile(profile);
+  const Suggestion suggestion = test::CreateAutofillSuggestion(
+      params.popup_item_id, u"baz foo", Suggestion::BackendId(profile.guid()));
+  // Wait until form is parsed. We only perform field by field filling if the
+  // AutofillField exists.
+  browser_autofill_manager_->OnFormsSeen({queried_form_}, {});
+  task_environment_.RunUntilIdle();
+  base::HistogramTester histogram_tester;
+  external_delegate_->DidAcceptSuggestion(suggestion,
+                                          /*position=*/0,
+                                          kDefaultTriggerSource);
+
+  histogram_tester.ExpectUniqueSample("Autofill.FillingMethodUsed.",
+                                      params.target_metric, 1);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    AutofillExternalDelegateUnitTest,
+    FillingMethodMetricsUnitTest,
+    ::testing::ValuesIn(kFillingMethodMetricsTestCases),
+    [](const ::testing::TestParamInfo<FillingMethodMetricsUnitTest::ParamType>&
+           info) { return info.param.test_name; });
+
 // Test parameter data for asserting that group filling suggestions
 // forward the expected fields to the manager.
 struct GroupFillingTestParams {
@@ -1282,7 +1350,7 @@
 
   IssueOnQuery();
   browser_autofill_manager_->OnFormsSeen({queried_form_}, {});
-  // Wait until for is parsed.
+  // Wait until form is parsed.
   task_environment_.RunUntilIdle();
   ON_CALL(personal_data(), IsAutofillProfileEnabled)
       .WillByDefault(Return(true));
@@ -1685,7 +1753,7 @@
   EXPECT_CALL(autofill_client_,
               HideAutofillPopup(PopupHidingReason::kAcceptSuggestion));
   IssueOnQuery();
-  // Wait until for is parsed. We only perform field by field filling if the
+  // Wait until form is parsed. We only perform field by field filling if the
   // AutofillField exists.
   browser_autofill_manager_->OnFormsSeen({queried_form_}, {});
   task_environment_.RunUntilIdle();
@@ -1709,7 +1777,7 @@
   EXPECT_CALL(autofill_client_,
               HideAutofillPopup(PopupHidingReason::kAcceptSuggestion));
   IssueOnQuery();
-  // Wait until for is parsed. We only perform field by field filling if the
+  // Wait until form is parsed. We only perform field by field filling if the
   // AutofillField exists.
   browser_autofill_manager_->OnFormsSeen({queried_form_}, {});
   task_environment_.RunUntilIdle();
@@ -1746,13 +1814,19 @@
   const auto kExpectedSuggestions =
   // On Desktop, the GPay icon should be stored in the store indicator icon.
 #if BUILDFLAG(IS_ANDROID)
-      SuggestionVectorIconsAre(std::string(), StartsWith("googlePay"));
+      SuggestionVectorIconsAre(Suggestion::Icon::kNoIcon,
+                               AnyOf(Suggestion::Icon::kGooglePay,
+                                     Suggestion::Icon::kGooglePayDark));
 #elif BUILDFLAG(IS_IOS)
-      SuggestionVectorIconsAre(std::string(), std::string(),
-                               StartsWith("googlePay"));
+      SuggestionVectorIconsAre(Suggestion::Icon::kNoIcon,
+                               Suggestion::Icon::kNoIcon,
+                               AnyOf(Suggestion::Icon::kGooglePay,
+                                     Suggestion::Icon::kGooglePayDark));
 #else
-      SuggestionVectorStoreIndicatorIconsAre(std::string(), std::string(),
-                                             StartsWith("googlePay"));
+      SuggestionVectorStoreIndicatorIconsAre(
+          Suggestion::Icon::kNoIcon, Suggestion::Icon::kNoIcon,
+          AnyOf(Suggestion::Icon::kGooglePay,
+                Suggestion::Icon::kGooglePayDark));
 #endif
   EXPECT_CALL(autofill_client_,
               ShowAutofillPopup(PopupOpenArgsAre(kExpectedSuggestions), _));
@@ -1767,11 +1841,12 @@
        ShouldNotShowGooglePayIconIfSuggestionsContainLocalCards) {
   IssueOnQuery();
 
-  const auto kExpectedSuggestions = SuggestionVectorIconsAre(std::string(),
+  const auto kExpectedSuggestions =
+      SuggestionVectorIconsAre(Suggestion::Icon::kNoIcon,
 #if !BUILDFLAG(IS_ANDROID)
-                                                             std::string(),
+                               Suggestion::Icon::kNoIcon,
 #endif
-                                                             "settingsIcon");
+                               Suggestion::Icon::kSettings);
   EXPECT_CALL(autofill_client_,
               ShowAutofillPopup(PopupOpenArgsAre(kExpectedSuggestions), _));
   std::vector<Suggestion> autofill_item;
diff --git a/components/autofill/core/browser/autofill_suggestion_generator.cc b/components/autofill/core/browser/autofill_suggestion_generator.cc
index 1744e544..306f76a8 100644
--- a/components/autofill/core/browser/autofill_suggestion_generator.cc
+++ b/components/autofill/core/browser/autofill_suggestion_generator.cc
@@ -113,7 +113,7 @@
   Suggestion suggestion(l10n_util::GetStringUTF16(
       IDS_AUTOFILL_EDIT_ADDRESS_PROFILE_POPUP_OPTION_SELECTED));
   suggestion.popup_item_id = PopupItemId::kEditAddressProfile;
-  suggestion.icon = "editIcon";
+  suggestion.icon = Suggestion::Icon::kEdit;
   suggestion.payload = backend_id;
   suggestion.acceptance_a11y_announcement = l10n_util::GetStringUTF16(
       IDS_AUTOFILL_A11Y_ANNOUNCE_EDIT_ADDRESS_PROFILE_POPUP_OPTION_SELECTED);
@@ -125,7 +125,7 @@
   Suggestion suggestion(l10n_util::GetStringUTF16(
       IDS_AUTOFILL_DELETE_ADDRESS_PROFILE_POPUP_OPTION_SELECTED));
   suggestion.popup_item_id = PopupItemId::kDeleteAddressProfile;
-  suggestion.icon = "deleteIcon";
+  suggestion.icon = Suggestion::Icon::kDelete;
   suggestion.payload = backend_id;
   suggestion.acceptance_a11y_announcement = l10n_util::GetStringUTF16(
       IDS_AUTOFILL_A11Y_ANNOUNCE_DELETE_ADDRESS_PROFILE_POPUP_OPTION_SELECTED);
@@ -164,7 +164,7 @@
   Suggestion suggestion(l10n_util::GetStringUTF16(
       IDS_AUTOFILL_FILL_EVERYTHING_FROM_ADDRESS_PROFILE_POPUP_OPTION_SELECTED));
   suggestion.popup_item_id = PopupItemId::kFillEverythingFromAddressProfile;
-  suggestion.icon = "magicIcon";
+  suggestion.icon = Suggestion::Icon::kMagic;
   suggestion.payload = backend_id;
   suggestion.acceptance_a11y_announcement = l10n_util::GetStringUTF16(
       IDS_AUTOFILL_A11Y_ANNOUNCE_FILL_EVERYTHING_FROM_ADDRESS_PROFILE_POPUP_OPTION_SELECTED);
@@ -174,15 +174,25 @@
 // Append new suggestions to `suggestions` based on the `ServerFieldType` list
 // provided. Suggestions are not added if their info is not found in the
 // provided `profile`. Returns true if any suggestion was added.
-bool AddFieldByFieldSuggestions(const std::vector<ServerFieldType>& types,
+bool AddFieldByFieldSuggestions(const std::vector<ServerFieldType>& field_types,
                                 const AutofillProfile& profile,
                                 const std::string& app_locale,
                                 std::vector<Suggestion>& suggestions) {
   bool any_suggestion_added = false;
-  for (auto type : types) {
-    std::u16string value = profile.GetInfo(type, app_locale);
-    if (!value.empty()) {
-      suggestions.emplace_back(value, PopupItemId::kFieldByFieldFilling);
+  for (auto field_type : field_types) {
+    // This is not how suggestion main text is built in general.
+    // (See AutofillSuggestionGenerator::GetProfileSuggestionMainText)
+    // However, since the only special case is ADDRESS_HOME_STREET_ADDRESS
+    // we can safely replace the function call by the line below, since field
+    // by field suggestions are not generated for that type.
+    CHECK(field_type != ADDRESS_HOME_STREET_ADDRESS);
+    std::u16string suggestion_main_text =
+        profile.GetInfo(field_type, app_locale);
+    if (!suggestion_main_text.empty()) {
+      suggestions.emplace_back(suggestion_main_text,
+                               PopupItemId::kFieldByFieldFilling);
+      suggestions.back().field_by_field_filling_type_used =
+          std::optional(field_type);
       any_suggestion_added = true;
     }
   }
@@ -320,7 +330,15 @@
     phone_number_suggestion.popup_item_id =
         is_phone_field ? PopupItemId::kFillFullPhoneNumber
                        : PopupItemId::kFieldByFieldFilling;
-    phone_number_suggestion.payload = Suggestion::BackendId(profile.guid());
+    if (phone_number_suggestion.popup_item_id ==
+        PopupItemId::kFieldByFieldFilling) {
+      phone_number_suggestion.field_by_field_filling_type_used =
+          std::optional(PHONE_HOME_WHOLE_NUMBER);
+    } else {
+      // `PopupItemId::kFieldByFieldFilling` suggestions do not use profile,
+      // therefore only set the backend id in the group filling case.
+      phone_number_suggestion.payload = Suggestion::BackendId(profile.guid());
+    }
     suggestion.children.push_back(std::move(phone_number_suggestion));
     phone_number_suggestion_added = true;
   }
@@ -334,7 +352,15 @@
     email_address_suggestion.popup_item_id =
         is_email_field ? PopupItemId::kFillFullEmail
                        : PopupItemId::kFieldByFieldFilling;
-    email_address_suggestion.payload = Suggestion::BackendId(profile.guid());
+    if (email_address_suggestion.popup_item_id ==
+        PopupItemId::kFieldByFieldFilling) {
+      email_address_suggestion.field_by_field_filling_type_used =
+          std::optional(EMAIL_ADDRESS);
+    } else {
+      // `PopupItemId::kFieldByFieldFilling` suggestions do not use profile,
+      // therefore only set the backend id in the group filling case.
+      email_address_suggestion.payload = Suggestion::BackendId(profile.guid());
+    }
     suggestion.children.push_back(std::move(email_address_suggestion));
     email_address_suggestion_added = true;
   }
@@ -663,7 +689,7 @@
   Suggestion suggestion(u"Devtools", PopupItemId::kDevtoolsTestAddresses);
   suggestion.labels = {{Suggestion::Text(
       l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_TEST_DATA))}};
-  suggestion.icon = "codeIcon";
+  suggestion.icon = Suggestion::Icon::kCode;
   for (const AutofillProfile& test_address : test_addresses) {
     const std::u16string test_address_country =
         test_address.GetInfo(ADDRESS_HOME_COUNTRY, locale);
@@ -795,9 +821,10 @@
       const bool fill_full_form = true;
       if (base::FeatureList::IsEnabled(
               features::kAutofillGranularFillingAvailable)) {
-        suggestions.back().icon = fill_full_form ? "locationIcon" : "";
+        suggestions.back().icon = fill_full_form ? Suggestion::Icon::kLocation
+                                                 : Suggestion::Icon::kNoIcon;
       } else {
-        suggestions.back().icon = "accountIcon";
+        suggestions.back().icon = Suggestion::Icon::kAccount;
       }
     }
 
@@ -1150,7 +1177,7 @@
   Suggestion suggestion(
       l10n_util::GetStringUTF16(IDS_AUTOFILL_MANAGE_PAYMENT_METHODS));
   suggestion.popup_item_id = PopupItemId::kAutofillOptions;
-  suggestion.icon = "settingsIcon";
+  suggestion.icon = Suggestion::Icon::kSettings;
   return suggestion;
 }
 
@@ -1276,7 +1303,7 @@
     // will navigate to the url in |footer_offer_details_url| if the footer is
     // selected in AutofillExternalDelegate::DidAcceptSuggestion().
     suggestion.payload = std::move(footer_offer_details_url);
-    suggestion.trailing_icon = "google";
+    suggestion.trailing_icon = Suggestion::Icon::kGoogle;
   }
   return suggestions;
 }
@@ -1388,7 +1415,7 @@
 #if BUILDFLAG(IS_ANDROID)
       suggestion.feature_for_iph =
           feature_engagement::kIPHKeyboardAccessoryPaymentOfferFeature.name;
-      suggestion.icon = "offerTag";
+      suggestion.icon = Suggestion::Icon::kOfferTag;
 #endif
     } else {
       // On Desktop/Android dropdown, populate an offer label.
diff --git a/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc b/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc
index d5e539a..d0907d5 100644
--- a/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc
+++ b/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc
@@ -57,7 +57,7 @@
 using testing::Field;
 using testing::Matcher;
 
-constexpr char kAddressEntryIcon[] = "accountIcon";
+constexpr Suggestion::Icon kAddressEntryIcon = Suggestion::Icon::kAccount;
 
 #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
 std::vector<std::vector<Suggestion::Text>> ConstructLabelLineMatrix(
@@ -70,12 +70,16 @@
   return Field(&Suggestion::popup_item_id, id);
 }
 
-Matcher<Suggestion> EqualsSuggestion(PopupItemId id,
-                                     const std::u16string& text) {
+Matcher<Suggestion> EqualsSuggestion(
+    PopupItemId id,
+    const std::u16string& main_text,
+    ServerFieldType field_by_field_filling_type_used) {
   return AllOf(
       Field(&Suggestion::popup_item_id, id),
       Field(&Suggestion::main_text,
-            Suggestion::Text(text, Suggestion::Text::IsPrimary(true))));
+            Suggestion::Text(main_text, Suggestion::Text::IsPrimary(true))),
+      Field(&Suggestion::field_by_field_filling_type_used,
+            std::optional(field_by_field_filling_type_used)));
 }
 
 Matcher<Suggestion> EqualsIbanSuggestion(
@@ -1179,24 +1183,32 @@
       ElementsAre(
           EqualsSuggestion(PopupItemId::kFillFullName),
           EqualsSuggestion(PopupItemId::kFieldByFieldFilling,
-                           profile().GetInfo(NAME_FIRST, app_locale())),
+                           profile().GetInfo(NAME_FIRST, app_locale()),
+                           NAME_FIRST),
           EqualsSuggestion(PopupItemId::kFieldByFieldFilling,
-                           profile().GetInfo(NAME_MIDDLE, app_locale())),
+                           profile().GetInfo(NAME_MIDDLE, app_locale()),
+                           NAME_MIDDLE),
           EqualsSuggestion(PopupItemId::kFieldByFieldFilling,
-                           profile().GetInfo(NAME_LAST, app_locale())),
+                           profile().GetInfo(NAME_LAST, app_locale()),
+                           NAME_LAST),
           EqualsSuggestion(PopupItemId::kSeparator),
           EqualsSuggestion(PopupItemId::kFieldByFieldFilling,
-                           profile().GetInfo(ADDRESS_HOME_LINE1, app_locale())),
+                           profile().GetInfo(ADDRESS_HOME_LINE1, app_locale()),
+                           ADDRESS_HOME_LINE1),
           EqualsSuggestion(PopupItemId::kFieldByFieldFilling,
-                           profile().GetInfo(ADDRESS_HOME_LINE2, app_locale())),
+                           profile().GetInfo(ADDRESS_HOME_LINE2, app_locale()),
+                           ADDRESS_HOME_LINE2),
           EqualsSuggestion(PopupItemId::kFieldByFieldFilling,
-                           profile().GetInfo(ADDRESS_HOME_ZIP, app_locale())),
+                           profile().GetInfo(ADDRESS_HOME_ZIP, app_locale()),
+                           ADDRESS_HOME_ZIP),
           EqualsSuggestion(PopupItemId::kSeparator),
           EqualsSuggestion(
               PopupItemId::kFieldByFieldFilling,
-              profile().GetInfo(PHONE_HOME_WHOLE_NUMBER, app_locale())),
+              profile().GetInfo(PHONE_HOME_WHOLE_NUMBER, app_locale()),
+              PHONE_HOME_WHOLE_NUMBER),
           EqualsSuggestion(PopupItemId::kFieldByFieldFilling,
-                           profile().GetInfo(EMAIL_ADDRESS, app_locale())),
+                           profile().GetInfo(EMAIL_ADDRESS, app_locale()),
+                           EMAIL_ADDRESS),
           EqualsSuggestion(PopupItemId::kSeparator),
           EqualsSuggestion(PopupItemId::kEditAddressProfile),
           EqualsSuggestion(PopupItemId::kDeleteAddressProfile)));
@@ -1217,10 +1229,12 @@
       suggestions[0].children[5].children,
       ElementsAre(EqualsSuggestion(PopupItemId::kFieldByFieldFilling,
                                    profile().GetInfo(ADDRESS_HOME_HOUSE_NUMBER,
-                                                     app_locale())),
-                  EqualsSuggestion(PopupItemId::kFieldByFieldFilling,
-                                   profile().GetInfo(ADDRESS_HOME_STREET_NAME,
-                                                     app_locale()))));
+                                                     app_locale()),
+                                   ADDRESS_HOME_HOUSE_NUMBER),
+                  EqualsSuggestion(
+                      PopupItemId::kFieldByFieldFilling,
+                      profile().GetInfo(ADDRESS_HOME_STREET_NAME, app_locale()),
+                      ADDRESS_HOME_STREET_NAME)));
   // House number and street name suggestions should have labels.
   EXPECT_EQ(suggestions[0].children[5].children[0].labels,
             std::vector<std::vector<Suggestion::Text>>(
@@ -1374,12 +1388,14 @@
   EXPECT_THAT(suggestions[0].children[1].children,
               ElementsAre(EqualsSuggestion(
                   PopupItemId::kFieldByFieldFilling,
-                  profile.GetInfo(ADDRESS_HOME_STREET_NAME, app_locale()))));
+                  profile.GetInfo(ADDRESS_HOME_STREET_NAME, app_locale()),
+                  ADDRESS_HOME_STREET_NAME)));
   // The address line 2 (seventh child) should have the house number as child.
   EXPECT_THAT(suggestions[0].children[2].children,
               ElementsAre(EqualsSuggestion(
                   PopupItemId::kFieldByFieldFilling,
-                  profile.GetInfo(ADDRESS_HOME_HOUSE_NUMBER, app_locale()))));
+                  profile.GetInfo(ADDRESS_HOME_HOUSE_NUMBER, app_locale()),
+                  ADDRESS_HOME_HOUSE_NUMBER)));
 }
 
 TEST_F(
@@ -2262,7 +2278,7 @@
   EXPECT_EQ(suggestions[0].labels[0].size(), 1u);
   EXPECT_EQ(suggestions[0].labels[0][0],
             Suggestion::Text(u"Address test data"));
-  EXPECT_EQ(suggestions[0].icon, "codeIcon");
+  EXPECT_EQ(suggestions[0].icon, Suggestion::Icon::kCode);
   EXPECT_EQ(suggestions[0].children.size(), 1u);
 
   const Suggestion& child = suggestions[0].children.back();
diff --git a/components/autofill/core/browser/autofill_test_utils.cc b/components/autofill/core/browser/autofill_test_utils.cc
index 0e85851..27656ac 100644
--- a/components/autofill/core/browser/autofill_test_utils.cc
+++ b/components/autofill/core/browser/autofill_test_utils.cc
@@ -770,6 +770,18 @@
   credit_card->set_billing_address_id(billing_address_id);
 }
 
+CreditCard CreateCreditCardWithInfo(const char* name_on_card,
+                                    const char* card_number,
+                                    const char* expiration_month,
+                                    const char* expiration_year,
+                                    const std::string& billing_address_id,
+                                    const std::u16string& cvc) {
+  CreditCard credit_card;
+  SetCreditCardInfo(&credit_card, name_on_card, card_number, expiration_month,
+                    expiration_year, billing_address_id, cvc);
+  return credit_card;
+}
+
 void DisableSystemServices(PrefService* prefs) {
   // Use a mock Keychain rather than the OS one to store credit card data.
   OSCryptMocker::SetUp();
diff --git a/components/autofill/core/browser/autofill_test_utils.h b/components/autofill/core/browser/autofill_test_utils.h
index 15b6f44..12b8d1af 100644
--- a/components/autofill/core/browser/autofill_test_utils.h
+++ b/components/autofill/core/browser/autofill_test_utils.h
@@ -285,6 +285,14 @@
                        const std::string& billing_address_id,
                        const std::u16string& cvc = u"");
 
+// Same as SetCreditCardInfo() but returns CreditCard object.
+CreditCard CreateCreditCardWithInfo(const char* name_on_card,
+                                    const char* card_number,
+                                    const char* expiration_month,
+                                    const char* expiration_year,
+                                    const std::string& billing_address_id,
+                                    const std::u16string& cvc = u"");
+
 // TODO(isherman): We should do this automatically for all tests, not manually
 // on a per-test basis: http://crbug.com/57221
 // Disables or mocks out code that would otherwise reach out to system services.
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc
index 40b9f6e..b935866 100644
--- a/components/autofill/core/browser/browser_autofill_manager.cc
+++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -3853,7 +3853,7 @@
   Suggestion suggestion(std::move(suggestion_text));
   suggestion.labels = {{Suggestion::Text(std::move(label_text))}};
   suggestion.popup_item_id = PopupItemId::kCompose;
-  suggestion.icon = "keyIcon";
+  suggestion.icon = Suggestion::Icon::kKey;
   return suggestion;
 }
 
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
index 3f6f65fc..26901ed 100644
--- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -141,7 +141,7 @@
 
 const std::string kArbitraryNickname = "Grocery Card";
 const std::u16string kArbitraryNickname16 = u"Grocery Card";
-const std::string kAddressEntryIcon = "accountIcon";
+Suggestion::Icon kAddressEntryIcon = Suggestion::Icon::kAccount;
 
 const std::string_view kPlusAddressSuggestionMetric =
     "Autofill.PlusAddresses.Suggestion.Events";
@@ -1674,8 +1674,10 @@
   // attribute.
   GetAutofillSuggestions(form, form.fields[0]);
   CheckSuggestions(form.fields[0].global_id(),
-                   Suggestion("Charles", "", "", PopupItemId::kAddressEntry),
-                   Suggestion("Elvis", "", "", PopupItemId::kAddressEntry));
+                   Suggestion("Charles", "", Suggestion::Icon::kNoIcon,
+                              PopupItemId::kAddressEntry),
+                   Suggestion("Elvis", "", Suggestion::Icon::kNoIcon,
+                              PopupItemId::kAddressEntry));
 
   // Check that there are no suggestions for the field without the autocomplete
   // attribute.
@@ -2028,8 +2030,9 @@
        OnSuggestionsReturned_CallsExternalDelegate) {
   FieldGlobalId field_id = test::MakeFieldGlobalId();
   std::vector<Suggestion> suggestions = {
-      Suggestion("Charles", "123 Apple St.", "", PopupItemId::kAddressEntry),
-      Suggestion("Elvis", "3734 Elvis Presley Blvd.", "",
+      Suggestion("Charles", "123 Apple St.", Suggestion::Icon::kNoIcon,
+                 PopupItemId::kAddressEntry),
+      Suggestion("Elvis", "3734 Elvis Presley Blvd.", Suggestion::Icon::kNoIcon,
                  PopupItemId::kAddressEntry)};
 
   browser_autofill_manager_->OnSuggestionsReturned(
@@ -2063,10 +2066,11 @@
       form.fields[1].global_id(),
       Suggestion(std::string("Visa  ") + test::ObfuscatedCardDigitsAsUTF8(
                                              "3456", ObfuscationLength()),
-                 visa_label, kVisaCard, PopupItemId::kCreditCardEntry),
+                 visa_label, Suggestion::Icon::kCardVisa,
+                 PopupItemId::kCreditCardEntry),
       Suggestion(std::string("Mastercard  ") + test::ObfuscatedCardDigitsAsUTF8(
                                                    "8765", ObfuscationLength()),
-                 master_card_label, kMasterCard,
+                 master_card_label, Suggestion::Icon::kCardMasterCard,
                  PopupItemId::kCreditCardEntry));
 }
 
@@ -2094,10 +2098,11 @@
       field.global_id(),
       Suggestion(std::string("Visa  ") + test::ObfuscatedCardDigitsAsUTF8(
                                              "3456", ObfuscationLength()),
-                 visa_label, kVisaCard, PopupItemId::kCreditCardEntry),
+                 visa_label, Suggestion::Icon::kCardVisa,
+                 PopupItemId::kCreditCardEntry),
       Suggestion(std::string("Mastercard  ") + test::ObfuscatedCardDigitsAsUTF8(
                                                    "8765", ObfuscationLength()),
-                 master_card_label, kMasterCard,
+                 master_card_label, Suggestion::Icon::kCardMasterCard,
                  PopupItemId::kCreditCardEntry));
 }
 
@@ -2125,10 +2130,11 @@
       field.global_id(),
       Suggestion(std::string("Visa  ") + test::ObfuscatedCardDigitsAsUTF8(
                                              "3456", ObfuscationLength()),
-                 visa_label, kVisaCard, PopupItemId::kCreditCardEntry),
+                 visa_label, Suggestion::Icon::kCardVisa,
+                 PopupItemId::kCreditCardEntry),
       Suggestion(std::string("Mastercard  ") + test::ObfuscatedCardDigitsAsUTF8(
                                                    "8765", ObfuscationLength()),
-                 master_card_label, kMasterCard,
+                 master_card_label, Suggestion::Icon::kCardMasterCard,
                  PopupItemId::kCreditCardEntry));
 }
 
@@ -2157,10 +2163,11 @@
       field.global_id(),
       Suggestion(std::string("Visa  ") + test::ObfuscatedCardDigitsAsUTF8(
                                              "3456", ObfuscationLength()),
-                 visa_label, kVisaCard, PopupItemId::kCreditCardEntry),
+                 visa_label, Suggestion::Icon::kCardVisa,
+                 PopupItemId::kCreditCardEntry),
       Suggestion(std::string("Mastercard  ") + test::ObfuscatedCardDigitsAsUTF8(
                                                    "8765", ObfuscationLength()),
-                 master_card_label, kMasterCard,
+                 master_card_label, Suggestion::Icon::kCardMasterCard,
                  PopupItemId::kCreditCardEntry));
 }
 
@@ -2195,7 +2202,7 @@
       field.global_id(),
       Suggestion(std::string("Mastercard  ") + test::ObfuscatedCardDigitsAsUTF8(
                                                    "3123", ObfuscationLength()),
-                 master_card_label, kMasterCard,
+                 master_card_label, Suggestion::Icon::kCardMasterCard,
                  PopupItemId::kCreditCardEntry));
 }
 
@@ -2221,7 +2228,8 @@
       field.global_id(),
       Suggestion(std::string("Visa  ") + test::ObfuscatedCardDigitsAsUTF8(
                                              "3456", ObfuscationLength()),
-                 visa_label, kVisaCard, PopupItemId::kCreditCardEntry));
+                 visa_label, Suggestion::Icon::kCardVisa,
+                 PopupItemId::kCreditCardEntry));
 }
 
 // Test that we return credit card profile suggestions when the selected form
@@ -2253,11 +2261,13 @@
 #endif
 
   // Test that we sent the right values to the external delegate.
-  CheckSuggestions(credit_card_number_field.global_id(),
-                   Suggestion(visa_value, visa_label, kVisaCard,
-                              PopupItemId::kCreditCardEntry),
-                   Suggestion(master_card_value, master_card_label, kMasterCard,
-                              PopupItemId::kCreditCardEntry));
+  CheckSuggestions(
+      credit_card_number_field.global_id(),
+      Suggestion(visa_value, visa_label, Suggestion::Icon::kCardVisa,
+                 PopupItemId::kCreditCardEntry),
+      Suggestion(master_card_value, master_card_label,
+                 Suggestion::Icon::kCardMasterCard,
+                 PopupItemId::kCreditCardEntry));
 }
 
 // Test that we return credit card profile suggestions when the selected form
@@ -2299,11 +2309,13 @@
 #endif
 
   // Test that we sent the right values to the external delegate.
-  CheckSuggestions(cardholder_name_field.global_id(),
-                   Suggestion("Elvis Presley", visa_label, kVisaCard,
-                              PopupItemId::kCreditCardEntry),
-                   Suggestion("Buddy Holly", master_card_label, kMasterCard,
-                              PopupItemId::kCreditCardEntry));
+  CheckSuggestions(
+      cardholder_name_field.global_id(),
+      Suggestion("Elvis Presley", visa_label, Suggestion::Icon::kCardVisa,
+                 PopupItemId::kCreditCardEntry),
+      Suggestion("Buddy Holly", master_card_label,
+                 Suggestion::Icon::kCardMasterCard,
+                 PopupItemId::kCreditCardEntry));
 }
 
 // Test that we return a warning explaining that credit card profile suggestions
@@ -2323,7 +2335,7 @@
   CheckSuggestions(
       form.fields[0].global_id(),
       Suggestion(l10n_util::GetStringUTF8(IDS_AUTOFILL_WARNING_MIXED_FORM), "",
-                 "", PopupItemId::kMixedFormMessage));
+                 Suggestion::Icon::kNoIcon, PopupItemId::kMixedFormMessage));
 
   // Clear the test credit cards and try again -- we should still show the
   // mixed form warning.
@@ -2332,7 +2344,7 @@
   CheckSuggestions(
       form.fields[0].global_id(),
       Suggestion(l10n_util::GetStringUTF8(IDS_AUTOFILL_WARNING_MIXED_FORM), "",
-                 "", PopupItemId::kMixedFormMessage));
+                 Suggestion::Icon::kNoIcon, PopupItemId::kMixedFormMessage));
 }
 
 // Test that we return credit card suggestions for secure pages that have an
@@ -2360,10 +2372,11 @@
       form.fields[1].global_id(),
       Suggestion(std::string("Visa  ") + test::ObfuscatedCardDigitsAsUTF8(
                                              "3456", ObfuscationLength()),
-                 visa_label, kVisaCard, PopupItemId::kCreditCardEntry),
+                 visa_label, Suggestion::Icon::kCardVisa,
+                 PopupItemId::kCreditCardEntry),
       Suggestion(std::string("Mastercard  ") + test::ObfuscatedCardDigitsAsUTF8(
                                                    "8765", ObfuscationLength()),
-                 master_card_label, kMasterCard,
+                 master_card_label, Suggestion::Icon::kCardMasterCard,
                  PopupItemId::kCreditCardEntry));
 }
 
@@ -2392,10 +2405,11 @@
       form.fields[1].global_id(),
       Suggestion(std::string("Visa  ") + test::ObfuscatedCardDigitsAsUTF8(
                                              "3456", ObfuscationLength()),
-                 visa_label, kVisaCard, PopupItemId::kCreditCardEntry),
+                 visa_label, Suggestion::Icon::kCardVisa,
+                 PopupItemId::kCreditCardEntry),
       Suggestion(std::string("Mastercard  ") + test::ObfuscatedCardDigitsAsUTF8(
                                                    "8765", ObfuscationLength()),
-                 master_card_label, kMasterCard,
+                 master_card_label, Suggestion::Icon::kCardMasterCard,
                  PopupItemId::kCreditCardEntry));
 }
 
@@ -2434,14 +2448,15 @@
       form.fields[1].global_id(),
       Suggestion(std::string("Visa  ") + test::ObfuscatedCardDigitsAsUTF8(
                                              "3456", ObfuscationLength()),
-                 visa_label, kVisaCard, PopupItemId::kCreditCardEntry),
+                 visa_label, Suggestion::Icon::kCardVisa,
+                 PopupItemId::kCreditCardEntry),
       Suggestion(std::string("Mastercard  ") + test::ObfuscatedCardDigitsAsUTF8(
                                                    "8765", ObfuscationLength()),
-                 master_card_label1, kMasterCard,
+                 master_card_label1, Suggestion::Icon::kCardMasterCard,
                  PopupItemId::kCreditCardEntry),
       Suggestion(std::string("Mastercard  ") + test::ObfuscatedCardDigitsAsUTF8(
                                                    "3456", ObfuscationLength()),
-                 master_card_label2, kMasterCard,
+                 master_card_label2, Suggestion::Icon::kCardMasterCard,
                  PopupItemId::kCreditCardEntry));
 }
 
@@ -2528,14 +2543,16 @@
       form.fields[1].global_id(),
       Suggestion(std::string("Mastercard  ") + test::ObfuscatedCardDigitsAsUTF8(
                                                    "5100", ObfuscationLength()),
-                 master_card_label, kMasterCard, PopupItemId::kCreditCardEntry),
+                 master_card_label, Suggestion::Icon::kCardMasterCard,
+                 PopupItemId::kCreditCardEntry),
       Suggestion(std::string("Amex  ") + test::ObfuscatedCardDigitsAsUTF8(
                                              "0005", ObfuscationLength()),
-                 amex_card_label, kAmericanExpressCard,
+                 amex_card_label, Suggestion::Icon::kCardAmericanExpress,
                  PopupItemId::kCreditCardEntry),
       Suggestion(std::string("Visa  ") + test::ObfuscatedCardDigitsAsUTF8(
                                              "3456", ObfuscationLength()),
-                 visa_label, kVisaCard, PopupItemId::kCreditCardEntry));
+                 visa_label, Suggestion::Icon::kCardVisa,
+                 PopupItemId::kCreditCardEntry));
 }
 
 // Test cards that are expired AND disused are suppressed when suppression is
@@ -2596,11 +2613,13 @@
         std::string(", expires on 04/10");
 #endif
 
-    CheckSuggestions(form.fields[0].global_id(),
-                     Suggestion("Bonnie Parker", mastercard_label, kMasterCard,
-                                PopupItemId::kCreditCardEntry),
-                     Suggestion("Clyde Barrow", visa_label, kVisaCard,
-                                PopupItemId::kCreditCardEntry));
+    CheckSuggestions(
+        form.fields[0].global_id(),
+        Suggestion("Bonnie Parker", mastercard_label,
+                   Suggestion::Icon::kCardMasterCard,
+                   PopupItemId::kCreditCardEntry),
+        Suggestion("Clyde Barrow", visa_label, Suggestion::Icon::kCardVisa,
+                   PopupItemId::kCreditCardEntry));
   }
 
   // Query with name prefix for card0 returns card0.
@@ -2620,7 +2639,8 @@
 #endif
 
     CheckSuggestions(form.fields[0].global_id(),
-                     Suggestion("Bonnie Parker", mastercard_label, kMasterCard,
+                     Suggestion("Bonnie Parker", mastercard_label,
+                                Suggestion::Icon::kCardMasterCard,
                                 PopupItemId::kCreditCardEntry));
   }
 
@@ -2640,9 +2660,10 @@
         std::string(", expires on 04/10");
 #endif
 
-    CheckSuggestions(form.fields[0].global_id(),
-                     Suggestion("Clyde Barrow", visa_label, kVisaCard,
-                                PopupItemId::kCreditCardEntry));
+    CheckSuggestions(
+        form.fields[0].global_id(),
+        Suggestion("Clyde Barrow", visa_label, Suggestion::Icon::kCardVisa,
+                   PopupItemId::kCreditCardEntry));
   }
 
   // Query with name prefix for card2 returns card2.
@@ -2661,10 +2682,10 @@
         std::string(", expires on 01/10");
 #endif
 
-    CheckSuggestions(
-        form.fields[0].global_id(),
-        Suggestion("John Dillinger", amex_label, kAmericanExpressCard,
-                   PopupItemId::kCreditCardEntry));
+    CheckSuggestions(form.fields[0].global_id(),
+                     Suggestion("John Dillinger", amex_label,
+                                Suggestion::Icon::kCardAmericanExpress,
+                                PopupItemId::kCreditCardEntry));
   }
 }
 
@@ -2713,7 +2734,7 @@
       form.fields[1].global_id(),
       Suggestion(std::string("Amex  ") + test::ObfuscatedCardDigitsAsUTF8(
                                              "0005", ObfuscationLength()),
-                 amex_card_exp_label, kAmericanExpressCard,
+                 amex_card_exp_label, Suggestion::Icon::kCardAmericanExpress,
                  PopupItemId::kCreditCardEntry));
 
   // Query by cardholder name field.
@@ -2731,9 +2752,10 @@
 
   CheckSuggestions(
       form.fields[0].global_id(),
-      Suggestion("John Dillinger", "", kGenericCard,
+      Suggestion("John Dillinger", "", Suggestion::Icon::kCardGeneric,
                  PopupItemId::kCreditCardEntry),
-      Suggestion("Clyde Barrow", amex_card_label, kAmericanExpressCard,
+      Suggestion("Clyde Barrow", amex_card_label,
+                 Suggestion::Icon::kCardAmericanExpress,
                  PopupItemId::kCreditCardEntry));
 }
 
@@ -2811,10 +2833,11 @@
   // Test that we sent the credit card suggestions to the external delegate.
   CheckSuggestions(
       field.global_id(),
-      Suggestion(MakeCardLabel("Visa", "3456"), visa_label, kVisaCard,
-                 PopupItemId::kCreditCardEntry),
+      Suggestion(MakeCardLabel("Visa", "3456"), visa_label,
+                 Suggestion::Icon::kCardVisa, PopupItemId::kCreditCardEntry),
       Suggestion(MakeCardLabel("Mastercard", "8765"), master_card_label,
-                 kMasterCard, PopupItemId::kCreditCardEntry));
+                 Suggestion::Icon::kCardMasterCard,
+                 PopupItemId::kCreditCardEntry));
 }
 
 // Test that for non-https forms with both address and credit card fields, we
@@ -2841,7 +2864,8 @@
       field.global_id(),
       Suggestion(
           l10n_util::GetStringUTF8(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION),
-          "", "", PopupItemId::kInsecureContextPaymentDisabledMessage));
+          "", Suggestion::Icon::kNoIcon,
+          PopupItemId::kInsecureContextPaymentDisabledMessage));
 
   // Clear the test credit cards and try again -- we shouldn't return a warning.
   personal_data().ClearCreditCards();
@@ -3521,8 +3545,10 @@
 
   // Test that we sent the right values to the external delegate.
   CheckSuggestions(form.fields.back().global_id(),
-                   Suggestion("one", "", "", PopupItemId::kAutocompleteEntry),
-                   Suggestion("two", "", "", PopupItemId::kAutocompleteEntry));
+                   Suggestion("one", "", Suggestion::Icon::kNoIcon,
+                              PopupItemId::kAutocompleteEntry),
+                   Suggestion("two", "", Suggestion::Icon::kNoIcon,
+                              PopupItemId::kAutocompleteEntry));
 }
 
 // The method `AutofillSuggestionGenerator::GetPrefixMatchedProfiles` prevents
@@ -8200,7 +8226,8 @@
       form.fields[3].global_id(),
       Suggestion(std::string("Visa  ") + test::ObfuscatedCardDigitsAsUTF8(
                                              "3456", ObfuscationLength()),
-                 visa_label, kVisaCard, PopupItemId::kCreditCardEntry));
+                 visa_label, Suggestion::Icon::kCardVisa,
+                 PopupItemId::kCreditCardEntry));
 }
 
 // Test that inputs detected to be CVC inputs are forced to
@@ -8647,17 +8674,19 @@
   std::string label = std::string("Expires on 04/99");
 #endif
 
-  Suggestion virtual_card_suggestion = Suggestion(
-      "Virtual card",
-      std::string("nickname  ") +
-          test::ObfuscatedCardDigitsAsUTF8("3456", ObfuscationLength()),
-      label, kVisaCard, autofill::PopupItemId::kVirtualCreditCardEntry);
+  Suggestion virtual_card_suggestion =
+      Suggestion("Virtual card",
+                 std::string("nickname  ") + test::ObfuscatedCardDigitsAsUTF8(
+                                                 "3456", ObfuscationLength()),
+                 label, Suggestion::Icon::kCardVisa,
+                 autofill::PopupItemId::kVirtualCreditCardEntry);
 
   CheckSuggestions(
       form.fields[1].global_id(), virtual_card_suggestion,
       Suggestion(std::string("nickname  ") + test::ObfuscatedCardDigitsAsUTF8(
                                                  "3456", ObfuscationLength()),
-                 label, kVisaCard, PopupItemId::kCreditCardEntry));
+                 label, Suggestion::Icon::kCardVisa,
+                 PopupItemId::kCreditCardEntry));
 
   // Non card number field (cardholder name field).
   GetAutofillSuggestions(form, form.fields[0]);
@@ -8671,19 +8700,22 @@
 #endif
 
   virtual_card_suggestion =
-      Suggestion("Virtual card", std::string("Elvis Presley"), label, kVisaCard,
+      Suggestion("Virtual card", std::string("Elvis Presley"), label,
+                 Suggestion::Icon::kCardVisa,
                  autofill::PopupItemId::kVirtualCreditCardEntry);
 
-  CheckSuggestions(form.fields[0].global_id(), virtual_card_suggestion,
-                   Suggestion("Elvis Presley", label, kVisaCard,
-                              PopupItemId::kCreditCardEntry));
+  CheckSuggestions(
+      form.fields[0].global_id(), virtual_card_suggestion,
+      Suggestion("Elvis Presley", label, Suggestion::Icon::kCardVisa,
+                 PopupItemId::kCreditCardEntry));
 
   // Incomplete form.
   GetAutofillSuggestions(form, form.fields[0]);
 
-  CheckSuggestions(form.fields[0].global_id(), virtual_card_suggestion,
-                   Suggestion("Elvis Presley", label, kVisaCard,
-                              PopupItemId::kCreditCardEntry));
+  CheckSuggestions(
+      form.fields[0].global_id(), virtual_card_suggestion,
+      Suggestion("Elvis Presley", label, Suggestion::Icon::kCardVisa,
+                 PopupItemId::kCreditCardEntry));
 }
 
 TEST_F(BrowserAutofillManagerTest,
@@ -9618,7 +9650,7 @@
   CheckSuggestions(
       form.fields.back().global_id(),
       Suggestion(l10n_util::GetStringUTF8(IDS_AUTOFILL_WARNING_MIXED_FORM), "",
-                 "", PopupItemId::kMixedFormMessage));
+                 Suggestion::Icon::kNoIcon, PopupItemId::kMixedFormMessage));
 }
 
 // Test that if a form is mixed content we do not show a warning if the opt out
@@ -9657,7 +9689,7 @@
   CheckSuggestions(
       form.fields.back().global_id(),
       Suggestion(l10n_util::GetStringUTF8(IDS_AUTOFILL_WARNING_MIXED_FORM), "",
-                 "", PopupItemId::kMixedFormMessage));
+                 Suggestion::Icon::kNoIcon, PopupItemId::kMixedFormMessage));
 
   // Pretend user started typing and make sure we no longer set suggestions.
   form.fields[0].value = u"Michael";
@@ -10125,8 +10157,10 @@
   GetAutofillSuggestions(form, form.fields[0]);
   CheckSuggestions(
       form.fields[0].global_id(),
-      Suggestion("buddy@gmail.com", "", "", PopupItemId::kAddressEntry),
-      Suggestion("theking@gmail.com", "", "", PopupItemId::kAddressEntry));
+      Suggestion("buddy@gmail.com", "", Suggestion::Icon::kNoIcon,
+                 PopupItemId::kAddressEntry),
+      Suggestion("theking@gmail.com", "", Suggestion::Icon::kNoIcon,
+                 PopupItemId::kAddressEntry));
 }
 
 // Tests that compose suggestions are not queried if Autofill has suggestions
@@ -10422,7 +10456,8 @@
                                       : expected_nickname_) +
               "  " +
               test::ObfuscatedCardDigitsAsUTF8("0005", ObfuscationLength()),
-          exp_label, kAmericanExpressCard, PopupItemId::kCreditCardEntry));
+          exp_label, Suggestion::Icon::kCardAmericanExpress,
+          PopupItemId::kCreditCardEntry));
 }
 
 TEST_P(BrowserAutofillManagerTestForSharingNickname,
@@ -10459,12 +10494,14 @@
           (local_nickname_.empty() ? std::string("Amex") : local_nickname_) +
               "  " +
               test::ObfuscatedCardDigitsAsUTF8("0005", ObfuscationLength()),
-          exp_label, kAmericanExpressCard, PopupItemId::kCreditCardEntry),
+          exp_label, Suggestion::Icon::kCardAmericanExpress,
+          PopupItemId::kCreditCardEntry),
       Suggestion(
           (server_nickname_.empty() ? std::string("Amex") : server_nickname_) +
               "  " +
               test::ObfuscatedCardDigitsAsUTF8("8431", ObfuscationLength()),
-          exp_label, kAmericanExpressCard, PopupItemId::kCreditCardEntry));
+          exp_label, Suggestion::Icon::kCardAmericanExpress,
+          PopupItemId::kCreditCardEntry));
 }
 
 // The following Refill Tests ensure that Autofill can handle the situation
@@ -10880,8 +10917,10 @@
   // to email fields.
   GetAutofillSuggestions(form, form.fields[0]);
   CheckSuggestions(form.fields[0].global_id(),
-                   Suggestion("Charles", "", "", PopupItemId::kAddressEntry),
-                   Suggestion("Elvis", "", "", PopupItemId::kAddressEntry));
+                   Suggestion("Charles", "", Suggestion::Icon::kNoIcon,
+                              PopupItemId::kAddressEntry),
+                   Suggestion("Elvis", "", Suggestion::Icon::kNoIcon,
+                              PopupItemId::kAddressEntry));
 
   // Also check that there are no suggestions for the field without the
   // autocomplete attribute, ensuring that unrecognized fields don't get plus
@@ -10911,9 +10950,11 @@
   GetAutofillSuggestions(form, form.fields[0]);
   CheckSuggestions(
       form.fields[0].global_id(),
-      Suggestion("buddy@gmail.com", "", "", PopupItemId::kAddressEntry),
-      Suggestion("theking@gmail.com", "", "", PopupItemId::kAddressEntry),
-      Suggestion("plus+plus@plus.plus", "", "",
+      Suggestion("buddy@gmail.com", "", Suggestion::Icon::kNoIcon,
+                 PopupItemId::kAddressEntry),
+      Suggestion("theking@gmail.com", "", Suggestion::Icon::kNoIcon,
+                 PopupItemId::kAddressEntry),
+      Suggestion("plus+plus@plus.plus", "", Suggestion::Icon::kNoIcon,
                  PopupItemId::kFillExistingPlusAddress));
   EXPECT_THAT(
       histogram_tester_.GetAllSamples(kPlusAddressSuggestionMetric),
@@ -10943,11 +10984,13 @@
   GetAutofillSuggestions(form, form.fields[0]);
   CheckSuggestions(
       form.fields[0].global_id(),
-      Suggestion("buddy@gmail.com", "", "", PopupItemId::kAddressEntry),
-      Suggestion("theking@gmail.com", "", "", PopupItemId::kAddressEntry),
+      Suggestion("buddy@gmail.com", "", Suggestion::Icon::kNoIcon,
+                 PopupItemId::kAddressEntry),
+      Suggestion("theking@gmail.com", "", Suggestion::Icon::kNoIcon,
+                 PopupItemId::kAddressEntry),
       Suggestion(
           base::UTF16ToUTF8(plus_address_service->GetCreateSuggestionLabel()),
-          "", "", PopupItemId::kCreateNewPlusAddress));
+          "", Suggestion::Icon::kNoIcon, PopupItemId::kCreateNewPlusAddress));
 
   EXPECT_THAT(histogram_tester_.GetAllSamples(kPlusAddressSuggestionMetric),
               BucketsAre(base::Bucket(plus_addresses::PlusAddressMetrics::
diff --git a/components/autofill/core/browser/data_model/credit_card.cc b/components/autofill/core/browser/data_model/credit_card.cc
index 0dc5bc2..c2ab0af 100644
--- a/components/autofill/core/browser/data_model/credit_card.cc
+++ b/components/autofill/core/browser/data_model/credit_card.cc
@@ -221,52 +221,64 @@
 }
 
 // static
-int CreditCard::IconResourceId(const std::string& network) {
+int CreditCard::IconResourceId(Suggestion::Icon icon) {
   bool should_show_metadata_icon = base::FeatureList::IsEnabled(
       features::kAutofillEnableNewCardArtAndNetworkImages);
 
-  if (network == kAmericanExpressCard)
+  if (icon == Suggestion::Icon::kCardAmericanExpress) {
     return should_show_metadata_icon ? IDR_AUTOFILL_METADATA_CC_AMEX
                                      : IDR_AUTOFILL_CC_AMEX;
-  if (network == kDinersCard)
+  }
+  if (icon == Suggestion::Icon::kCardDiners) {
     return should_show_metadata_icon ? IDR_AUTOFILL_METADATA_CC_DINERS
                                      : IDR_AUTOFILL_CC_DINERS;
-  if (network == kDiscoverCard) {
+  }
+  if (icon == Suggestion::Icon::kCardDiscover) {
     return should_show_metadata_icon ? IDR_AUTOFILL_METADATA_CC_DISCOVER
                                      : IDR_AUTOFILL_CC_DISCOVER;
   }
-  if (network == kEloCard)
+  if (icon == Suggestion::Icon::kCardElo) {
     return should_show_metadata_icon ? IDR_AUTOFILL_METADATA_CC_ELO
                                      : IDR_AUTOFILL_CC_ELO;
-  if (network == kJCBCard)
+  }
+  if (icon == Suggestion::Icon::kCardJCB) {
     return should_show_metadata_icon ? IDR_AUTOFILL_METADATA_CC_JCB
                                      : IDR_AUTOFILL_CC_JCB;
-  if (network == kMasterCard) {
+  }
+  if (icon == Suggestion::Icon::kCardMasterCard) {
     return should_show_metadata_icon ? IDR_AUTOFILL_METADATA_CC_MASTERCARD
                                      : IDR_AUTOFILL_CC_MASTERCARD;
   }
-  if (network == kMirCard)
+  if (icon == Suggestion::Icon::kCardMir) {
     return should_show_metadata_icon ? IDR_AUTOFILL_METADATA_CC_MIR
                                      : IDR_AUTOFILL_CC_MIR;
-  if (network == kTroyCard)
+  }
+  if (icon == Suggestion::Icon::kCardTroy) {
     return should_show_metadata_icon ? IDR_AUTOFILL_METADATA_CC_TROY
                                      : IDR_AUTOFILL_CC_TROY;
-  if (network == kUnionPay) {
+  }
+  if (icon == Suggestion::Icon::kCardUnionPay) {
     return should_show_metadata_icon ? IDR_AUTOFILL_METADATA_CC_UNIONPAY
                                      : IDR_AUTOFILL_CC_UNIONPAY;
   }
-  if (network == kVisaCard)
+  if (icon == Suggestion::Icon::kCardVisa) {
     return should_show_metadata_icon ? IDR_AUTOFILL_METADATA_CC_VISA
                                      : IDR_AUTOFILL_CC_VISA;
+  }
 
-  // If you hit this DCHECK, the above list of cases needs to be updated to
+  // If you hit this CHECK, the above list of cases needs to be updated to
   // include a new card.
-  DCHECK_EQ(kGenericCard, network);
+  CHECK_EQ(Suggestion::Icon::kCardGeneric, icon);
   return should_show_metadata_icon ? IDR_AUTOFILL_METADATA_CC_GENERIC
                                    : IDR_AUTOFILL_CC_GENERIC;
 }
 
 // static
+int CreditCard::IconResourceId(std::string_view icon_str) {
+  return IconResourceId(Suggestion::ConvertIconStringIntoIcon(icon_str));
+}
+
+// static
 const char* CreditCard::GetCardNetwork(const std::u16string& number) {
   // Credit card number specifications taken from:
   // https://en.wikipedia.org/wiki/Payment_card_number,
@@ -1058,8 +1070,8 @@
   return std::u16string(12, kMidlineEllipsisPlainDot) + LastFourDigits();
 }
 
-std::string CreditCard::CardIconStringForAutofillSuggestion() const {
-  return network_;
+Suggestion::Icon CreditCard::CardIconStringForAutofillSuggestion() const {
+  return Suggestion::ConvertIconStringIntoIcon(network_);
 }
 
 std::u16string CreditCard::NetworkAndLastFourDigits(
diff --git a/components/autofill/core/browser/data_model/credit_card.h b/components/autofill/core/browser/data_model/credit_card.h
index 969760b..6ee8d9c 100644
--- a/components/autofill/core/browser/data_model/credit_card.h
+++ b/components/autofill/core/browser/data_model/credit_card.h
@@ -11,10 +11,11 @@
 #include <utility>
 
 #include "base/gtest_prod_util.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "components/autofill/core/browser/data_model/autofill_data_model.h"
+#include "components/autofill/core/browser/ui/suggestion.h"
 #include "url/gurl.h"
 
 namespace autofill {
@@ -143,8 +144,13 @@
   // The user-visible issuer network of the card, e.g. 'Mastercard'.
   static std::u16string NetworkForDisplay(const std::string& network);
 
-  // The ResourceBundle ID for the appropriate card issuer network image.
-  static int IconResourceId(const std::string& network);
+  // The ResourceBundle ID for the appropriate card issuer icon.
+  static int IconResourceId(Suggestion::Icon icon);
+
+  // Converts string to Suggestion::Icon and calls the method above.
+  // TODO(crbug.com/1019660): Rename this method to
+  // "IconResourceIdFromCreditCardNetwork"
+  static int IconResourceId(std::string_view icon_str);
 
   // Returns the internal representation of card issuer network corresponding to
   // the given |number|.  The card issuer network is determined purely according
@@ -357,9 +363,12 @@
   // several fields.
   std::u16string ObfuscatedNumberWithVisibleLastFourDigitsForSplitFields()
       const;
-  // The string used to represent the icon to be used for the autofill
-  // suggestion. For ex: visaCC, googleIssuedCC, americanExpressCC, etc.
-  std::string CardIconStringForAutofillSuggestion() const;
+
+  // The icon to be used for the autofill suggestion. For example, icon for:
+  // visa, american express, etc.
+  // TODO(crbug.com/1019660): Rename to "CardIconForAutofillSuggestion"
+  Suggestion::Icon CardIconStringForAutofillSuggestion() const;
+
   // A label for this card formatted as 'IssuerNetwork ****2345'. By default,
   // the `obfuscation_length` is set to 4 which would add **** to the last four
   // digits of the card.
diff --git a/components/autofill/core/browser/field_types.h b/components/autofill/core/browser/field_types.h
index d45dced..a0a4d7b 100644
--- a/components/autofill/core/browser/field_types.h
+++ b/components/autofill/core/browser/field_types.h
@@ -7,7 +7,7 @@
 
 #include <type_traits>
 
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/types/cxx23_to_underlying.h"
 #include "components/autofill/core/common/dense_set.h"
 #include "components/autofill/core/common/html_field_types.h"
diff --git a/components/autofill/core/browser/form_data_importer_unittest.cc b/components/autofill/core/browser/form_data_importer_unittest.cc
index a211e6bf..5504197 100644
--- a/components/autofill/core/browser/form_data_importer_unittest.cc
+++ b/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -730,10 +730,8 @@
     personal_data_manager_->OnAcceptedLocalCreditCardSave(
         *extracted_credit_card);
 
-    CreditCard expected(base::Uuid::GenerateRandomV4().AsLowercaseString(),
-                        test::kEmptyOrigin);
-    test::SetCreditCardInfo(&expected, exp_name, exp_cc_num, exp_cc_month,
-                            exp_cc_year, "");
+    CreditCard expected = test::CreateCreditCardWithInfo(
+        exp_name, exp_cc_num, exp_cc_month, exp_cc_year, "");
     EXPECT_THAT(personal_data_manager_->GetCreditCards(),
                 UnorderedElementsCompareEqual(expected));
   }
@@ -1730,10 +1728,9 @@
       AutofillMetrics::HAS_CARD_NUMBER_AND_EXPIRATION_DATE, 1);
   personal_data_manager_->OnAcceptedLocalCreditCardSave(*extracted_credit_card);
 
-  CreditCard expected(base::Uuid::GenerateRandomV4().AsLowercaseString(),
-                      test::kEmptyOrigin);
-  test::SetCreditCardInfo(&expected, "Biggie Smalls", "4111111111111111", "01",
-                          "2999", "");  // Imported cards have no billing info.
+  CreditCard expected = test::CreateCreditCardWithInfo(
+      "Biggie Smalls", "4111111111111111", "01", "2999",
+      "");  // Imported cards have no billing info.
   EXPECT_THAT(personal_data_manager_->GetCreditCards(),
               UnorderedElementsCompareEqual(expected));
 }
@@ -1820,10 +1817,9 @@
   personal_data_manager_->OnAcceptedLocalCreditCardSave(*extracted_credit_card);
 
   // See that the invalid option text was converted to the right value.
-  CreditCard expected(base::Uuid::GenerateRandomV4().AsLowercaseString(),
-                      test::kEmptyOrigin);
-  test::SetCreditCardInfo(&expected, "Biggie Smalls", "4111111111111111", "02",
-                          "2999", "");  // Imported cards have no billing info.
+  CreditCard expected = test::CreateCreditCardWithInfo(
+      "Biggie Smalls", "4111111111111111", "02", "2999",
+      "");  // Imported cards have no billing info.
   EXPECT_THAT(personal_data_manager_->GetCreditCards(),
               UnorderedElementsCompareEqual(expected));
 }
@@ -1837,10 +1833,9 @@
   EXPECT_TRUE(extracted_credit_card);
   personal_data_manager_->OnAcceptedLocalCreditCardSave(*extracted_credit_card);
 
-  CreditCard expected(base::Uuid::GenerateRandomV4().AsLowercaseString(),
-                      test::kEmptyOrigin);
-  test::SetCreditCardInfo(&expected, "Biggie Smalls", "4111111111111111", "01",
-                          "2999", "");  // Imported cards have no billing info.
+  CreditCard expected = test::CreateCreditCardWithInfo(
+      "Biggie Smalls", "4111111111111111", "01", "2999",
+      "");  // Imported cards have no billing info.
   EXPECT_THAT(personal_data_manager_->GetCreditCards(),
               UnorderedElementsCompareEqual(expected));
 
@@ -1858,10 +1853,9 @@
   personal_data_manager_->OnAcceptedLocalCreditCardSave(
       *extracted_credit_card2);
 
-  CreditCard expected2(base::Uuid::GenerateRandomV4().AsLowercaseString(),
-                       test::kEmptyOrigin);
-  test::SetCreditCardInfo(&expected2, "", "5500000000000004", "02", "2999",
-                          "");  // Imported cards have no billing info.
+  CreditCard expected2 = test::CreateCreditCardWithInfo(
+      "", "5500000000000004", "02", "2999",
+      "");  // Imported cards have no billing info.
   // We ignore the order because multiple profiles or credit cards that
   // are added to the SQLite DB within the same second will be returned in GUID
   // (i.e., random) order.
@@ -2005,10 +1999,9 @@
   EXPECT_TRUE(extracted_credit_card);
   personal_data_manager_->OnAcceptedLocalCreditCardSave(*extracted_credit_card);
 
-  CreditCard expected(base::Uuid::GenerateRandomV4().AsLowercaseString(),
-                      test::kEmptyOrigin);
-  test::SetCreditCardInfo(&expected, "Biggie Smalls", "4111111111111111", "01",
-                          "2998", "");  // Imported cards have no billing info.
+  CreditCard expected = test::CreateCreditCardWithInfo(
+      "Biggie Smalls", "4111111111111111", "01", "2998",
+      "");  // Imported cards have no billing info.
   EXPECT_THAT(personal_data_manager_->GetCreditCards(),
               UnorderedElementsCompareEqual(expected));
 
@@ -2027,10 +2020,9 @@
 
   // Expect that the newer information is saved.  In this case the year is
   // updated to "2999".
-  CreditCard expected2(base::Uuid::GenerateRandomV4().AsLowercaseString(),
-                       test::kEmptyOrigin);
-  test::SetCreditCardInfo(&expected2, "Biggie Smalls", "4111111111111111", "01",
-                          "2999", "");  // Imported cards have no billing info.
+  CreditCard expected2 = test::CreateCreditCardWithInfo(
+      "Biggie Smalls", "4111111111111111", "01", "2999",
+      "");  // Imported cards have no billing info.
   const std::vector<CreditCard*>& results2 =
       personal_data_manager_->GetCreditCards();
   ASSERT_EQ(1U, results2.size());
@@ -2050,10 +2042,9 @@
   EXPECT_TRUE(extracted_credit_card);
   personal_data_manager_->OnAcceptedLocalCreditCardSave(*extracted_credit_card);
 
-  CreditCard expected(base::Uuid::GenerateRandomV4().AsLowercaseString(),
-                      test::kEmptyOrigin);
-  test::SetCreditCardInfo(&expected, "Biggie Smalls", "4111111111111111", "01",
-                          "2998", "");  // Imported cards have no billing info.
+  CreditCard expected = test::CreateCreditCardWithInfo(
+      "Biggie Smalls", "4111111111111111", "01", "2998",
+      "");  // Imported cards have no billing info.
   EXPECT_THAT(personal_data_manager_->GetCreditCards(),
               UnorderedElementsCompareEqual(expected));
 
@@ -2074,10 +2065,9 @@
 
   // Expect that the newer information is saved.  In this case the year is
   // updated to "2999".
-  CreditCard expected2(base::Uuid::GenerateRandomV4().AsLowercaseString(),
-                       test::kEmptyOrigin);
-  test::SetCreditCardInfo(&expected2, "Biggie Smalls", "4111111111111111", "01",
-                          "2999", "");  // Imported cards have no billing info.
+  CreditCard expected2 = test::CreateCreditCardWithInfo(
+      "Biggie Smalls", "4111111111111111", "01", "2999",
+      "");  // Imported cards have no billing info.
   const std::vector<CreditCard*>& results2 =
       personal_data_manager_->GetCreditCards();
   ASSERT_EQ(1U, results2.size());
@@ -2098,10 +2088,9 @@
   EXPECT_TRUE(extracted_credit_card);
   personal_data_manager_->OnAcceptedLocalCreditCardSave(*extracted_credit_card);
 
-  CreditCard expected(base::Uuid::GenerateRandomV4().AsLowercaseString(),
-                      test::kEmptyOrigin);
-  test::SetCreditCardInfo(&expected, "Biggie Smalls", "4111111111111111", "01",
-                          "2998", "");  // Imported cards have no billing info.
+  CreditCard expected = test::CreateCreditCardWithInfo(
+      "Biggie Smalls", "4111111111111111", "01", "2998",
+      "");  // Imported cards have no billing info.
   EXPECT_THAT(personal_data_manager_->GetCreditCards(),
               UnorderedElementsCompareEqual(expected));
 
@@ -2118,10 +2107,8 @@
   EXPECT_FALSE(extracted_credit_card2);
 
   // No change is expected.
-  CreditCard expected2(base::Uuid::GenerateRandomV4().AsLowercaseString(),
-                       test::kEmptyOrigin);
-  test::SetCreditCardInfo(&expected2, "Biggie Smalls", "4111111111111111", "01",
-                          "2998", "");
+  CreditCard expected2 = test::CreateCreditCardWithInfo(
+      "Biggie Smalls", "4111111111111111", "01", "2998", "");
   const std::vector<CreditCard*>& results2 =
       personal_data_manager_->GetCreditCards();
   ASSERT_EQ(1U, results2.size());
@@ -2141,10 +2128,8 @@
   EXPECT_TRUE(extracted_credit_card);
   personal_data_manager_->OnAcceptedLocalCreditCardSave(*extracted_credit_card);
 
-  CreditCard expected(base::Uuid::GenerateRandomV4().AsLowercaseString(),
-                      test::kEmptyOrigin);
-  test::SetCreditCardInfo(&expected, "Biggie Smalls", "4111111111111111", "01",
-                          "2999", "");
+  CreditCard expected = test::CreateCreditCardWithInfo(
+      "Biggie Smalls", "4111111111111111", "01", "2999", "");
   EXPECT_THAT(personal_data_manager_->GetCreditCards(),
               UnorderedElementsCompareEqual(expected));
 
@@ -2161,10 +2146,8 @@
   EXPECT_TRUE(extracted_credit_card2);
 
   // No change is expected.
-  CreditCard expected2(base::Uuid::GenerateRandomV4().AsLowercaseString(),
-                       test::kEmptyOrigin);
-  test::SetCreditCardInfo(&expected2, "Biggie Smalls", "4111111111111111", "01",
-                          "2999", "");
+  CreditCard expected2 = test::CreateCreditCardWithInfo(
+      "Biggie Smalls", "4111111111111111", "01", "2999", "");
   const std::vector<CreditCard*>& results2 =
       personal_data_manager_->GetCreditCards();
   ASSERT_EQ(1U, results2.size());
@@ -2184,10 +2167,8 @@
   EXPECT_FALSE(extracted_credit_card3);
 
   // No change is expected.
-  CreditCard expected3(base::Uuid::GenerateRandomV4().AsLowercaseString(),
-                       test::kEmptyOrigin);
-  test::SetCreditCardInfo(&expected3, "Biggie Smalls", "4111111111111111", "01",
-                          "2999", "");
+  CreditCard expected3 = test::CreateCreditCardWithInfo(
+      "Biggie Smalls", "4111111111111111", "01", "2999", "");
   const std::vector<CreditCard*>& results3 =
       personal_data_manager_->GetCreditCards();
   ASSERT_EQ(1U, results3.size());
@@ -2223,10 +2204,8 @@
 
   // Expect that the newer information is saved.  In this case the year is
   // added to the existing credit card.
-  CreditCard expected2(base::Uuid::GenerateRandomV4().AsLowercaseString(),
-                       test::kEmptyOrigin);
-  test::SetCreditCardInfo(&expected2, "Biggie Smalls", "4111111111111111", "01",
-                          "2999", "1");
+  CreditCard expected2 = test::CreateCreditCardWithInfo(
+      "Biggie Smalls", "4111111111111111", "01", "2999", "1");
   const std::vector<CreditCard*>& results2 =
       personal_data_manager_->GetCreditCards();
   ASSERT_EQ(1U, results2.size());
@@ -2802,10 +2781,8 @@
   EXPECT_THAT(*results_addr[0], ComparesEqual(expected_address));
 
   // Test that the credit card has also been saved.
-  CreditCard expected_card(base::Uuid::GenerateRandomV4().AsLowercaseString(),
-                           test::kEmptyOrigin);
-  test::SetCreditCardInfo(&expected_card, "Biggie Smalls", "4111111111111111",
-                          "01", "2999", "");
+  CreditCard expected_card = test::CreateCreditCardWithInfo(
+      "Biggie Smalls", "4111111111111111", "01", "2999", "");
   const std::vector<CreditCard*>& results_cards =
       personal_data_manager_->GetCreditCards();
   ASSERT_EQ(1U, results_cards.size());
@@ -2836,10 +2813,8 @@
   EXPECT_EQ(2U, personal_data_manager_->GetProfiles().size());
 
   // Test that the credit card has been saved.
-  CreditCard expected_card(base::Uuid::GenerateRandomV4().AsLowercaseString(),
-                           test::kEmptyOrigin);
-  test::SetCreditCardInfo(&expected_card, "Biggie Smalls", "4111111111111111",
-                          "01", "2999", "");
+  CreditCard expected_card = test::CreateCreditCardWithInfo(
+      "Biggie Smalls", "4111111111111111", "01", "2999", "");
   const std::vector<CreditCard*>& results =
       personal_data_manager_->GetCreditCards();
   ASSERT_EQ(1U, results.size());
@@ -2968,10 +2943,8 @@
   EXPECT_EQ(0U, personal_data_manager_->GetProfiles().size());
 
   // Test that the credit card has been saved.
-  CreditCard expected_card(base::Uuid::GenerateRandomV4().AsLowercaseString(),
-                           test::kEmptyOrigin);
-  test::SetCreditCardInfo(&expected_card, "Biggie Smalls", "4111111111111111",
-                          "01", "2999", "");
+  CreditCard expected_card = test::CreateCreditCardWithInfo(
+      "Biggie Smalls", "4111111111111111", "01", "2999", "");
   const std::vector<CreditCard*>& results =
       personal_data_manager_->GetCreditCards();
   ASSERT_EQ(1U, results.size());
@@ -3096,10 +3069,8 @@
       *extracted_data.extracted_credit_card);
 
   // Test that the credit card has been saved.
-  CreditCard expected_card(base::Uuid::GenerateRandomV4().AsLowercaseString(),
-                           test::kEmptyOrigin);
-  test::SetCreditCardInfo(&expected_card, "Biggie Smalls", "4111111111111111",
-                          "01", "2999", "");
+  CreditCard expected_card = test::CreateCreditCardWithInfo(
+      "Biggie Smalls", "4111111111111111", "01", "2999", "");
   const std::vector<CreditCard*>& results =
       personal_data_manager_->GetCreditCards();
   ASSERT_EQ(1U, results.size());
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index fcfc0b28..96266e6 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -713,14 +713,15 @@
     }
   }
 #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
-  if (base::FeatureList::IsEnabled(features::kAutofillOverridePredictions)) {
+  if (base::FeatureList::IsEnabled(
+          features::test::kAutofillOverridePredictions)) {
     InsertParsedOverrides(
         ParseServerPredictionOverrides(
-            features::kAutofillOverridePredictionsSpecification.Get()),
+            features::test::kAutofillOverridePredictionsSpecification.Get()),
         fields_suggestions);
     InsertParsedOverrides(
         ParseServerPredictionOverrides(
-            features::
+            features::test::
                 kAutofillOverridePredictionsForAlternativeFormSignaturesSpecification
                     .Get()),
         fields_suggestions);
@@ -754,11 +755,10 @@
     return current_field;
   };
   // Precedence rule for prediction sources is the following:
-  // Server/Manual overrides first then crowdsourcing of any type.
-  // Moreover, Autofill deprioritizes any crowdsourcing that only returned
-  // NO_SERVER_DATA (This is not done for overrides because overriding a field
-  // as not classifiable could be desirable).
-  // TODO(crbug.com/1495758): Prioritize manual overrides over server overrides.
+  // Manual overrides first, then server overrides, then crowdsourcing of any
+  // type. Moreover, Autofill deprioritizes any crowdsourcing that only returned
+  // NO_SERVER_DATA. This is not done for overrides because overriding a field
+  // as not classifiable could be desirable.
   auto get_suggestion_priority = [](std::optional<FieldSuggestion> suggestion) {
     if (!suggestion || suggestion->predictions().empty()) {
       return 0;
@@ -777,8 +777,9 @@
                    ? 1
                    : 0;
       case FieldPrediction::SOURCE_OVERRIDE:
-      case FieldPrediction::SOURCE_MANUAL_OVERRIDE:
         return 2;
+      case FieldPrediction::SOURCE_MANUAL_OVERRIDE:
+        return 3;
     }
   };
 
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc
index 46e57c12d..9d8ade6 100644
--- a/components/autofill/core/browser/form_structure_unittest.cc
+++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -111,7 +111,7 @@
 
 #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
 // Creates the override specification passed as a parameter to
-// `features::kAutofillOverridePredictions`.
+// `features::test::kAutofillOverridePredictions`.
 std::string CreateManualOverridePrediction(
     const std::vector<ManualOverride>& overrides) {
   std::vector<std::string> override_specs;
@@ -5331,12 +5331,12 @@
   // Only the prediction for the first field is overridden.
   base::test::ScopedFeatureList features;
   base::FieldTrialParams feature_parameters{
-      {features::kAutofillOverridePredictionsSpecification.name,
+      {features::test::kAutofillOverridePredictionsSpecification.name,
        CreateManualOverridePrediction({{CalculateFormSignature(form),
                                         CalculateFieldSignatureForField(field1),
                                         {USERNAME}}})}};
   features.InitAndEnableFeatureWithParameters(
-      features::kAutofillOverridePredictions, feature_parameters);
+      features::test::kAutofillOverridePredictions, feature_parameters);
 
   // Make serialized API response.
   AutofillQueryResponse api_response;
@@ -5396,12 +5396,12 @@
   // through".
   base::test::ScopedFeatureList features;
   base::FieldTrialParams feature_parameters{
-      {features::kAutofillOverridePredictionsSpecification.name,
+      {features::test::kAutofillOverridePredictionsSpecification.name,
        CreateManualOverridePrediction(
            {{kFormSignature, kFieldSignature, {NAME_FIRST}},
             {kFormSignature, kFieldSignature, {}}})}};
   features.InitAndEnableFeatureWithParameters(
-      features::kAutofillOverridePredictions, feature_parameters);
+      features::test::kAutofillOverridePredictions, feature_parameters);
 
   // Make serialized API response.
   AutofillQueryResponse api_response;
@@ -5457,12 +5457,12 @@
   // through".
   base::test::ScopedFeatureList features;
   base::FieldTrialParams feature_parameters{
-      {features::kAutofillOverridePredictionsSpecification.name,
+      {features::test::kAutofillOverridePredictionsSpecification.name,
        CreateManualOverridePrediction(
            {{kFormSignature, kFieldSignature, {NAME_FIRST}},
             {kFormSignature, kFieldSignature, {}}})}};
   features.InitAndEnableFeatureWithParameters(
-      features::kAutofillOverridePredictions, feature_parameters);
+      features::test::kAutofillOverridePredictions, feature_parameters);
 
   // Make serialized API response.
   AutofillQueryResponse api_response;
@@ -5536,13 +5536,13 @@
   // through".
   base::test::ScopedFeatureList features;
   base::FieldTrialParams feature_parameters{
-      {features::kAutofillOverridePredictionsSpecification.name,
+      {features::test::kAutofillOverridePredictionsSpecification.name,
        CreateManualOverridePrediction(
            {{kFormSignature, kFieldSignature, {NAME_FIRST}},
             {kFormSignature, kFieldSignature, {}},
             {kFormSignature, kFieldSignature, {COMPANY_NAME}}})}};
   features.InitAndEnableFeatureWithParameters(
-      features::kAutofillOverridePredictions, feature_parameters);
+      features::test::kAutofillOverridePredictions, feature_parameters);
 
   // Make serialized API response.
   AutofillQueryResponse api_response;
@@ -5601,14 +5601,14 @@
   // Only the prediction for the first field is overridden.
   base::test::ScopedFeatureList features;
   base::FieldTrialParams feature_parameters{
-      {features::
+      {features::test::
            kAutofillOverridePredictionsForAlternativeFormSignaturesSpecification
                .name,
        CreateManualOverridePrediction({{CalculateAlternativeFormSignature(form),
                                         CalculateFieldSignatureForField(field1),
                                         {USERNAME}}})}};
   features.InitAndEnableFeatureWithParameters(
-      features::kAutofillOverridePredictions, feature_parameters);
+      features::test::kAutofillOverridePredictions, feature_parameters);
 
   // Make serialized API response.
   AutofillQueryResponse api_response;
@@ -5660,14 +5660,14 @@
   // Only the prediction for the first field is overridden.
   base::test::ScopedFeatureList features;
   base::FieldTrialParams feature_parameters{
-      {features::
+      {features::test::
            kAutofillOverridePredictionsForAlternativeFormSignaturesSpecification
                .name,
        CreateManualOverridePrediction({{CalculateAlternativeFormSignature(form),
                                         CalculateFieldSignatureForField(field1),
                                         {USERNAME}}})}};
   features.InitAndEnableFeatureWithParameters(
-      features::kAutofillOverridePredictions, feature_parameters);
+      features::test::kAutofillOverridePredictions, feature_parameters);
 
   // Make serialized API response.
   AutofillQueryResponse api_response;
@@ -5697,6 +5697,61 @@
               ElementsAre(EqualsPrediction(
                   PASSWORD, FieldPrediction::SOURCE_PASSWORDS_DEFAULT)));
 }
+
+// Tests that server overrides have lower priority than manual overrides.
+TEST_F(FormStructureTestImpl,
+       ParseApiQueryResponseReplaceServerOverrideWithManualOverride) {
+  FormFieldData name_field =
+      CreateTestFormField("name", "name", "", FormControlType::kInputText);
+  FormFieldData password_field = CreateTestFormField(
+      "password", "password", "", FormControlType::kInputText);
+  FormData form;
+  form.fields = {name_field, password_field};
+  form.url = GURL("http://foo.com");
+  FormStructure form_structure(form);
+  std::vector<FormStructure*> forms{&form_structure};
+
+  // The feature is only initialized here because the parameters contain the
+  // form and field signatures. Only the prediction for the first field is
+  // overridden.
+  base::test::ScopedFeatureList features;
+  base::FieldTrialParams feature_parameters{
+      {features::test::
+           kAutofillOverridePredictionsForAlternativeFormSignaturesSpecification
+               .name,
+       CreateManualOverridePrediction(
+           {{CalculateAlternativeFormSignature(form),
+             CalculateFieldSignatureForField(name_field),
+             {USERNAME}}})}};
+  features.InitAndEnableFeatureWithParameters(
+      features::test::kAutofillOverridePredictions, feature_parameters);
+
+  // Make serialized API response.
+  AutofillQueryResponse api_response;
+  auto* form_suggestion = api_response.add_form_suggestions();
+  AddFieldPredictionsToForm(
+      form.fields[0],
+      {CreateFieldPrediction(EMAIL_ADDRESS, FieldPrediction::SOURCE_OVERRIDE)},
+      form_suggestion);
+  AddFieldPredictionsToForm(
+      form.fields[1],
+      {CreateFieldPrediction(PASSWORD, FieldPrediction::SOURCE_OVERRIDE)},
+      form_suggestion);
+
+  FormStructure::ParseApiQueryResponse(SerializeAndEncode(api_response), forms,
+                                       test::GetEncodedSignatures(forms),
+                                       nullptr, nullptr);
+
+  ASSERT_EQ(forms[0]->field_count(), 2u);
+
+  // The prediction for the first field comes from the manual override.
+  EXPECT_THAT(forms[0]->field(0)->server_predictions(),
+              ElementsAre(EqualsPrediction(
+                  USERNAME, FieldPrediction::SOURCE_MANUAL_OVERRIDE)));
+  EXPECT_THAT(forms[0]->field(1)->server_predictions(),
+              ElementsAre(EqualsPrediction(PASSWORD,
+                                           FieldPrediction::SOURCE_OVERRIDE)));
+}
 #endif
 
 // Tests ParseApiQueryResponse when the payload cannot be parsed to an
diff --git a/components/autofill/core/browser/geo/autofill_country.cc b/components/autofill/core/browser/geo/autofill_country.cc
index 16ba7be..5b26bf64 100644
--- a/components/autofill/core/browser/geo/autofill_country.cc
+++ b/components/autofill/core/browser/geo/autofill_country.cc
@@ -12,7 +12,7 @@
 #include "base/containers/fixed_flat_set.h"
 
 #include "base/feature_list.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "components/autofill/core/browser/geo/address_i18n.h"
 #include "components/autofill/core/browser/geo/country_data.h"
diff --git a/components/autofill/core/browser/iban_manager_unittest.cc b/components/autofill/core/browser/iban_manager_unittest.cc
index 68ab62a..accd266 100644
--- a/components/autofill/core/browser/iban_manager_unittest.cc
+++ b/components/autofill/core/browser/iban_manager_unittest.cc
@@ -128,7 +128,7 @@
     Suggestion footer_suggestion(
         l10n_util::GetStringUTF16(IDS_AUTOFILL_MANAGE_PAYMENT_METHODS));
     footer_suggestion.popup_item_id = PopupItemId::kAutofillOptions;
-    footer_suggestion.icon = "settingsIcon";
+    footer_suggestion.icon = Suggestion::Icon::kSettings;
     return footer_suggestion;
   }
 
diff --git a/components/autofill/core/browser/metrics/autofill_metrics.h b/components/autofill/core/browser/metrics/autofill_metrics.h
index 42517ac..a66a53e 100644
--- a/components/autofill/core/browser/metrics/autofill_metrics.h
+++ b/components/autofill/core/browser/metrics/autofill_metrics.h
@@ -16,7 +16,7 @@
 #include "base/containers/flat_set.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/raw_ref.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "components/autofill/core/browser/autofill_client.h"
 #include "components/autofill/core/browser/autofill_progress_dialog_type.h"
diff --git a/components/autofill/core/browser/metrics/granular_filling_metrics.cc b/components/autofill/core/browser/metrics/granular_filling_metrics.cc
index 3e4d1896..b48926e 100644
--- a/components/autofill/core/browser/metrics/granular_filling_metrics.cc
+++ b/components/autofill/core/browser/metrics/granular_filling_metrics.cc
@@ -20,8 +20,7 @@
 
 void LogFillingMethodUsed(AutofillFillingMethodMetric filling_method) {
   CHECK_LE(filling_method, AutofillFillingMethodMetric::kMaxValue);
-  base::UmaHistogramEnumeration("Autofill.FillingMethodUsed.", filling_method,
-                                AutofillFillingMethodMetric::kMaxValue);
+  base::UmaHistogramEnumeration("Autofill.FillingMethodUsed.", filling_method);
 }
 
 }  // namespace autofill::autofill_metrics
diff --git a/components/autofill/core/browser/metrics/granular_filling_metrics.h b/components/autofill/core/browser/metrics/granular_filling_metrics.h
index 1ee22e6..1d63389 100644
--- a/components/autofill/core/browser/metrics/granular_filling_metrics.h
+++ b/components/autofill/core/browser/metrics/granular_filling_metrics.h
@@ -8,7 +8,7 @@
 namespace autofill::autofill_metrics {
 
 // Represents the filling method chosen by the user.
-enum AutofillFillingMethodMetric {
+enum class AutofillFillingMethodMetric {
   // User chose to fill the whole form. Either from the main suggestion or from
   // the extended menu `PopupItemId::kFillEverything`.
   kFullForm = 0,
diff --git a/components/autofill/core/browser/ui/autofill_resource_utils.cc b/components/autofill/core/browser/ui/autofill_resource_utils.cc
index ec0db68..a72370e3 100644
--- a/components/autofill/core/browser/ui/autofill_resource_utils.cc
+++ b/components/autofill/core/browser/ui/autofill_resource_utils.cc
@@ -4,8 +4,6 @@
 
 #include "components/autofill/core/browser/ui/autofill_resource_utils.h"
 
-#include <string_view>
-
 #include "base/containers/fixed_flat_map.h"
 #include "build/branding_buildflags.h"
 #include "build/build_config.h"
@@ -25,65 +23,72 @@
 // Used in the IDS_ space as a placeholder for resources that don't exist.
 constexpr int kResourceNotFoundId = 0;
 
-constexpr auto kDataResources = base::MakeFixedFlatMap<std::string_view, int>({
-  {kAmericanExpressCard, IDR_AUTOFILL_CC_AMEX},
-      {kDinersCard, IDR_AUTOFILL_CC_DINERS},
-      {kDiscoverCard, IDR_AUTOFILL_CC_DISCOVER},
-      {kEloCard, IDR_AUTOFILL_CC_ELO}, {kGenericCard, IDR_AUTOFILL_CC_GENERIC},
-      {kJCBCard, IDR_AUTOFILL_CC_JCB},
-      {kMasterCard, IDR_AUTOFILL_CC_MASTERCARD},
-      {kMirCard, IDR_AUTOFILL_CC_MIR}, {kTroyCard, IDR_AUTOFILL_CC_TROY},
-      {kUnionPay, IDR_AUTOFILL_CC_UNIONPAY}, {kVisaCard, IDR_AUTOFILL_CC_VISA},
+constexpr auto kDataResources = base::MakeFixedFlatMap<Suggestion::Icon, int>({
+  {Suggestion::Icon::kCardAmericanExpress, IDR_AUTOFILL_CC_AMEX},
+      {Suggestion::Icon::kCardDiners, IDR_AUTOFILL_CC_DINERS},
+      {Suggestion::Icon::kCardDiscover, IDR_AUTOFILL_CC_DISCOVER},
+      {Suggestion::Icon::kCardElo, IDR_AUTOFILL_CC_ELO},
+      {Suggestion::Icon::kCardGeneric, IDR_AUTOFILL_CC_GENERIC},
+      {Suggestion::Icon::kCardJCB, IDR_AUTOFILL_CC_JCB},
+      {Suggestion::Icon::kCardMasterCard, IDR_AUTOFILL_CC_MASTERCARD},
+      {Suggestion::Icon::kCardMir, IDR_AUTOFILL_CC_MIR},
+      {Suggestion::Icon::kCardTroy, IDR_AUTOFILL_CC_TROY},
+      {Suggestion::Icon::kCardUnionPay, IDR_AUTOFILL_CC_UNIONPAY},
+      {Suggestion::Icon::kCardVisa, IDR_AUTOFILL_CC_VISA},
 #if BUILDFLAG(IS_ANDROID)
-      {"httpWarning", IDR_ANDROID_AUTOFILL_HTTP_WARNING},
-      {"httpsInvalid", IDR_ANDROID_AUTOFILL_HTTPS_INVALID_WARNING},
-      {"scanCreditCardIcon", IDR_ANDROID_AUTOFILL_CC_SCAN_NEW},
-      {"settings", IDR_ANDROID_AUTOFILL_SETTINGS},
-      {"create", IDR_ANDROID_AUTOFILL_CREATE},
-      {"offerTag", IDR_ANDROID_AUTOFILL_OFFER_TAG_GREEN},
+      {Suggestion::Icon::kHttpWarning, IDR_ANDROID_AUTOFILL_HTTP_WARNING},
+      {Suggestion::Icon::kHttpsInvalid,
+       IDR_ANDROID_AUTOFILL_HTTPS_INVALID_WARNING},
+      {Suggestion::Icon::kScanCreditCard, IDR_ANDROID_AUTOFILL_CC_SCAN_NEW},
+      {Suggestion::Icon::kSettingsAndroid, IDR_ANDROID_AUTOFILL_SETTINGS},
+      {Suggestion::Icon::kCreate, IDR_ANDROID_AUTOFILL_CREATE},
+      {Suggestion::Icon::kOfferTag, IDR_ANDROID_AUTOFILL_OFFER_TAG_GREEN},
 #endif  // BUILDFLAG(IS_ANDROID)
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
-      {"googlePay", IDR_AUTOFILL_GOOGLE_PAY},
+      {Suggestion::Icon::kGooglePay, IDR_AUTOFILL_GOOGLE_PAY},
 #if !BUILDFLAG(IS_ANDROID)
-      {"googlePayDark", IDR_AUTOFILL_GOOGLE_PAY_DARK},
-#endif  // NOT OS_ANDROID
+      {Suggestion::Icon::kGooglePayDark, IDR_AUTOFILL_GOOGLE_PAY_DARK},
+#endif  // !BUILDFLAG(IS_ANDROID)
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
 });
 
 constexpr auto kNewCardArtAndNetworkDataResources =
-    base::MakeFixedFlatMap<std::string_view, int>({
-      {kAmericanExpressCard, IDR_AUTOFILL_METADATA_CC_AMEX},
-          {kDinersCard, IDR_AUTOFILL_METADATA_CC_DINERS},
-          {kDiscoverCard, IDR_AUTOFILL_METADATA_CC_DISCOVER},
-          {kEloCard, IDR_AUTOFILL_METADATA_CC_ELO},
-          {kGenericCard, IDR_AUTOFILL_METADATA_CC_GENERIC},
-          {kJCBCard, IDR_AUTOFILL_METADATA_CC_JCB},
-          {kMasterCard, IDR_AUTOFILL_METADATA_CC_MASTERCARD},
-          {kMirCard, IDR_AUTOFILL_METADATA_CC_MIR},
-          {kTroyCard, IDR_AUTOFILL_METADATA_CC_TROY},
-          {kUnionPay, IDR_AUTOFILL_METADATA_CC_UNIONPAY},
-          {kVisaCard, IDR_AUTOFILL_METADATA_CC_VISA},
+    base::MakeFixedFlatMap<Suggestion::Icon, int>({
+      {Suggestion::Icon::kCardAmericanExpress, IDR_AUTOFILL_METADATA_CC_AMEX},
+          {Suggestion::Icon::kCardDiners, IDR_AUTOFILL_METADATA_CC_DINERS},
+          {Suggestion::Icon::kCardDiscover, IDR_AUTOFILL_METADATA_CC_DISCOVER},
+          {Suggestion::Icon::kCardElo, IDR_AUTOFILL_METADATA_CC_ELO},
+          {Suggestion::Icon::kCardGeneric, IDR_AUTOFILL_METADATA_CC_GENERIC},
+          {Suggestion::Icon::kCardJCB, IDR_AUTOFILL_METADATA_CC_JCB},
+          {Suggestion::Icon::kCardMasterCard,
+           IDR_AUTOFILL_METADATA_CC_MASTERCARD},
+          {Suggestion::Icon::kCardMir, IDR_AUTOFILL_METADATA_CC_MIR},
+          {Suggestion::Icon::kCardTroy, IDR_AUTOFILL_METADATA_CC_TROY},
+          {Suggestion::Icon::kCardUnionPay, IDR_AUTOFILL_METADATA_CC_UNIONPAY},
+          {Suggestion::Icon::kCardVisa, IDR_AUTOFILL_METADATA_CC_VISA},
 #if BUILDFLAG(IS_ANDROID)
-          {"httpWarning", IDR_ANDROID_AUTOFILL_HTTP_WARNING},
-          {"httpsInvalid", IDR_ANDROID_AUTOFILL_HTTPS_INVALID_WARNING},
-          {"scanCreditCardIcon", IDR_ANDROID_AUTOFILL_CC_SCAN_NEW},
-          {"settings", IDR_ANDROID_AUTOFILL_SETTINGS},
-          {"create", IDR_ANDROID_AUTOFILL_CREATE},
-          {"offerTag", IDR_ANDROID_AUTOFILL_OFFER_TAG_GREEN},
+          {Suggestion::Icon::kHttpWarning, IDR_ANDROID_AUTOFILL_HTTP_WARNING},
+          {Suggestion::Icon::kHttpsInvalid,
+           IDR_ANDROID_AUTOFILL_HTTPS_INVALID_WARNING},
+          {Suggestion::Icon::kScanCreditCard, IDR_ANDROID_AUTOFILL_CC_SCAN_NEW},
+          {Suggestion::Icon::kSettingsAndroid, IDR_ANDROID_AUTOFILL_SETTINGS},
+          {Suggestion::Icon::kCreate, IDR_ANDROID_AUTOFILL_CREATE},
+          {Suggestion::Icon::kOfferTag, IDR_ANDROID_AUTOFILL_OFFER_TAG_GREEN},
 #endif  // BUILDFLAG(IS_ANDROID)
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
-          {"googlePay", IDR_AUTOFILL_GOOGLE_PAY},
+          {Suggestion::Icon::kGooglePay, IDR_AUTOFILL_GOOGLE_PAY},
 #if !BUILDFLAG(IS_ANDROID)
-          {"googlePayDark", IDR_AUTOFILL_GOOGLE_PAY_DARK},
-#endif  // NOT OS_ANDROID
+          {Suggestion::Icon::kGooglePayDark, IDR_AUTOFILL_GOOGLE_PAY_DARK},
+#endif  // !BUILDFLAG(IS_ANDROID)
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
     });
 
 }  // namespace
 
-int GetIconResourceID(std::string_view resource_name) {
+int GetIconResourceID(Suggestion::Icon resource_name) {
 #if !BUILDFLAG(GOOGLE_CHROME_BRANDING)
-  if (resource_name == "googlePay" || resource_name == "googlePayDark") {
+  if (resource_name == Suggestion::Icon::kGooglePay ||
+      resource_name == Suggestion::Icon::kGooglePayDark) {
     return 0;
   }
 #endif
diff --git a/components/autofill/core/browser/ui/autofill_resource_utils.h b/components/autofill/core/browser/ui/autofill_resource_utils.h
index 1169790..62caf809b 100644
--- a/components/autofill/core/browser/ui/autofill_resource_utils.h
+++ b/components/autofill/core/browser/ui/autofill_resource_utils.h
@@ -5,12 +5,12 @@
 #ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_UI_AUTOFILL_RESOURCE_UTILS_H_
 #define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_AUTOFILL_RESOURCE_UTILS_H_
 
-#include <string_view>
+#include "components/autofill/core/browser/ui/suggestion.h"
 
 namespace autofill {
 
 // Returns the icon resource id corresponding to the |resource_name|.
-int GetIconResourceID(std::string_view resource_name);
+int GetIconResourceID(Suggestion::Icon resource_name);
 
 }  // namespace autofill
 
diff --git a/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller.h b/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller.h
index ed0fb74..de0eaef 100644
--- a/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller.h
+++ b/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller.h
@@ -33,7 +33,7 @@
   virtual int GetCvcImageRid() const = 0;
   virtual bool ShouldRequestExpirationDate() const = 0;
 #if BUILDFLAG(IS_ANDROID)
-  virtual std::string GetCardIconString() const = 0;
+  virtual Suggestion::Icon GetCardIcon() const = 0;
   virtual std::u16string GetCardName() const = 0;
   virtual std::u16string GetCardLastFourDigits() const = 0;
   virtual std::u16string GetCardExpiration() const = 0;
diff --git a/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.cc b/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.cc
index 87fe9a9..7059259 100644
--- a/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.cc
+++ b/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.cc
@@ -298,7 +298,7 @@
 }
 
 #if BUILDFLAG(IS_ANDROID)
-std::string CardUnmaskPromptControllerImpl::GetCardIconString() const {
+Suggestion::Icon CardUnmaskPromptControllerImpl::GetCardIcon() const {
   return card_.CardIconStringForAutofillSuggestion();
 }
 
diff --git a/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.h b/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.h
index cbc1e1f..2e0190344 100644
--- a/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.h
+++ b/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.h
@@ -64,7 +64,7 @@
   int GetCvcImageRid() const override;
   bool ShouldRequestExpirationDate() const override;
 #if BUILDFLAG(IS_ANDROID)
-  std::string GetCardIconString() const override;
+  Suggestion::Icon GetCardIcon() const override;
   std::u16string GetCardName() const override;
   std::u16string GetCardLastFourDigits() const override;
   std::u16string GetCardExpiration() const override;
diff --git a/components/autofill/core/browser/ui/suggestion.cc b/components/autofill/core/browser/ui/suggestion.cc
index 70a2d33..3ab5269 100644
--- a/components/autofill/core/browser/ui/suggestion.cc
+++ b/components/autofill/core/browser/ui/suggestion.cc
@@ -9,6 +9,7 @@
 
 #include "base/strings/utf_string_conversions.h"
 #include "base/types/cxx23_to_underlying.h"
+#include "components/autofill/core/browser/data_model/credit_card.h"
 #include "components/autofill/core/browser/ui/popup_item_ids.h"
 
 namespace autofill {
@@ -37,6 +38,121 @@
   return !operator==(text);
 }
 
+// static
+Suggestion::Icon Suggestion::ConvertIconStringIntoIcon(
+    std::string_view icon_string) {
+  if (icon_string == kAmericanExpressCard) {
+    return Suggestion::Icon::kCardAmericanExpress;
+  }
+  if (icon_string == kDinersCard) {
+    return Suggestion::Icon::kCardDiners;
+  }
+  if (icon_string == kDiscoverCard) {
+    return Suggestion::Icon::kCardDiscover;
+  }
+  if (icon_string == kEloCard) {
+    return Suggestion::Icon::kCardElo;
+  }
+  if (icon_string == kJCBCard) {
+    return Suggestion::Icon::kCardJCB;
+  }
+  if (icon_string == kMasterCard) {
+    return Suggestion::Icon::kCardMasterCard;
+  }
+  if (icon_string == kMirCard) {
+    return Suggestion::Icon::kCardMir;
+  }
+  if (icon_string == kTroyCard) {
+    return Suggestion::Icon::kCardTroy;
+  }
+  if (icon_string == kUnionPay) {
+    return Suggestion::Icon::kCardUnionPay;
+  }
+  if (icon_string == kVisaCard) {
+    return Suggestion::Icon::kCardVisa;
+  }
+  if (icon_string == kGenericCard) {
+    return Suggestion::Icon::kCardGeneric;
+  }
+
+  if (icon_string == "accountIcon") {
+    return Suggestion::Icon::kAccount;
+  }
+  if (icon_string == "clearIcon") {
+    return Suggestion::Icon::kClear;
+  }
+  if (icon_string == "create") {
+    return Suggestion::Icon::kCreate;
+  }
+  if (icon_string == "codeIcon") {
+    return Suggestion::Icon::kCode;
+  }
+  if (icon_string == "deleteIcon") {
+    return Suggestion::Icon::kDelete;
+  }
+  if (icon_string == "device") {
+    return Suggestion::Icon::kDevice;
+  }
+  if (icon_string == "editIcon") {
+    return Suggestion::Icon::kEdit;
+  }
+  if (icon_string == "empty") {
+    return Suggestion::Icon::kEmpty;
+  }
+  if (icon_string == "globeIcon") {
+    return Suggestion::Icon::kGlobe;
+  }
+  if (icon_string == "google") {
+    return Suggestion::Icon::kGoogle;
+  }
+  if (icon_string == "googlePasswordManager") {
+    return Suggestion::Icon::kGooglePasswordManager;
+  }
+  if (icon_string == "googlePay") {
+    return Suggestion::Icon::kGooglePay;
+  }
+  if (icon_string == "googlePayDark") {
+    return Suggestion::Icon::kGooglePayDark;
+  }
+  if (icon_string == "httpWarning") {
+    return Suggestion::Icon::kHttpWarning;
+  }
+  if (icon_string == "httpsInvalid") {
+    return Suggestion::Icon::kHttpsInvalid;
+  }
+  if (icon_string == "keyIcon") {
+    return Suggestion::Icon::kKey;
+  }
+  if (icon_string == "locationIcon") {
+    return Suggestion::Icon::kLocation;
+  }
+  if (icon_string == "magicIcon") {
+    return Suggestion::Icon::kMagic;
+  }
+  if (icon_string == "offerTag") {
+    return Suggestion::Icon::kOfferTag;
+  }
+  if (icon_string == "penSparkIcon") {
+    return Suggestion::Icon::kPenSpark;
+  }
+  if (icon_string == "scanCreditCardIcon") {
+    return Suggestion::Icon::kScanCreditCard;
+  }
+  if (icon_string == "settingsIcon") {
+    return Suggestion::Icon::kSettings;
+  }
+  if (icon_string == "settings") {
+    return Suggestion::Icon::kSettingsAndroid;
+  }
+  if (icon_string == "undoIcon") {
+    return Suggestion::Icon::kUndo;
+  }
+  if (icon_string == "") {
+    return Suggestion::Icon::kNoIcon;
+  }
+  NOTREACHED_NORETURN();
+}
+
 Suggestion::Suggestion() = default;
 
 Suggestion::Suggestion(std::u16string main_text)
@@ -51,11 +167,11 @@
 
 Suggestion::Suggestion(base::StringPiece main_text,
                        base::StringPiece label,
-                       std::string icon,
+                       Icon icon,
                        PopupItemId popup_item_id)
     : popup_item_id(popup_item_id),
       main_text(base::UTF8ToUTF16(main_text), Text::IsPrimary(true)),
-      icon(std::move(icon)) {
+      icon(icon) {
   if (!label.empty())
     this->labels = {{Text(base::UTF8ToUTF16(label))}};
 }
@@ -63,12 +179,12 @@
 Suggestion::Suggestion(base::StringPiece main_text,
                        base::StringPiece minor_text,
                        base::StringPiece label,
-                       std::string icon,
+                       Icon icon,
                        PopupItemId popup_item_id)
     : popup_item_id(popup_item_id),
       main_text(base::UTF8ToUTF16(main_text), Text::IsPrimary(true)),
       minor_text(base::UTF8ToUTF16(minor_text)),
-      icon(std::move(icon)) {
+      icon(icon) {
   if (!label.empty())
     this->labels = {{Text(base::UTF8ToUTF16(label))}};
 }
@@ -81,4 +197,97 @@
 
 Suggestion::~Suggestion() = default;
 
+std::string_view ConvertIconToPrintableString(Suggestion::Icon icon) {
+  switch (icon) {
+    case Suggestion::Icon::kAccount:
+      return "kAccount";
+    case Suggestion::Icon::kClear:
+      return "kClear";
+    case Suggestion::Icon::kCreate:
+      return "kCreate";
+    case Suggestion::Icon::kCode:
+      return "kCode";
+    case Suggestion::Icon::kDelete:
+      return "kDelete";
+    case Suggestion::Icon::kDevice:
+      return "kDevice";
+    case Suggestion::Icon::kEdit:
+      return "kEdit";
+    case Suggestion::Icon::kEmpty:
+      return "kEmpty";
+    case Suggestion::Icon::kGlobe:
+      return "kGlobe";
+    case Suggestion::Icon::kGoogle:
+      return "kGoogle";
+    case Suggestion::Icon::kGooglePasswordManager:
+      return "kGooglePasswordManager";
+    case Suggestion::Icon::kGooglePay:
+      return "kGooglePay";
+    case Suggestion::Icon::kGooglePayDark:
+      return "kGooglePayDark";
+    case Suggestion::Icon::kHttpWarning:
+      return "kHttpWarning";
+    case Suggestion::Icon::kHttpsInvalid:
+      return "kHttpsInvalid";
+    case Suggestion::Icon::kKey:
+      return "kKey";
+    case Suggestion::Icon::kLocation:
+      return "kLocation";
+    case Suggestion::Icon::kMagic:
+      return "kMagic";
+    case Suggestion::Icon::kOfferTag:
+      return "kOfferTag";
+    case Suggestion::Icon::kPenSpark:
+      return "kPenSpark";
+    case Suggestion::Icon::kScanCreditCard:
+      return "kScanCreditCard";
+    case Suggestion::Icon::kSettings:
+      return "kSettings";
+    case Suggestion::Icon::kSettingsAndroid:
+      return "kSettingsAndroid";
+    case Suggestion::Icon::kUndo:
+      return "kUndo";
+    case Suggestion::Icon::kCardGeneric:
+      return "kCardGeneric";
+    case Suggestion::Icon::kCardAmericanExpress:
+      return "kCardAmericanExpress";
+    case Suggestion::Icon::kCardDiners:
+      return "kCardDiners";
+    case Suggestion::Icon::kCardDiscover:
+      return "kCardDiscover";
+    case Suggestion::Icon::kCardElo:
+      return "kCardElo";
+    case Suggestion::Icon::kCardJCB:
+      return "kCardJCB";
+    case Suggestion::Icon::kCardMasterCard:
+      return "kCardMasterCard";
+    case Suggestion::Icon::kCardMir:
+      return "kCardMir";
+    case Suggestion::Icon::kCardTroy:
+      return "kCardTroy";
+    case Suggestion::Icon::kCardUnionPay:
+      return "kCardUnionPay";
+    case Suggestion::Icon::kCardVisa:
+      return "kCardVisa";
+    case Suggestion::Icon::kNoIcon:
+      return "kNoIcon";
+    default:
+      NOTREACHED_NORETURN();
+  }
+}
+
+void PrintTo(const Suggestion& suggestion, std::ostream* os) {
+  *os << std::endl
+      << "Suggestion (popup_item_id:"
+      << base::to_underlying(suggestion.popup_item_id) << ", main_text:\""
+      << suggestion.main_text.value << "\""
+      << (suggestion.main_text.is_primary ? "(Primary)" : "(Not Primary)")
+      << ", minor_text:\"" << suggestion.minor_text.value << "\""
+      << (suggestion.minor_text.is_primary ? "(Primary)" : "(Not Primary)")
+      << ", additional_label: \"" << suggestion.additional_label << "\""
+      << ", icon:" << ConvertIconToPrintableString(suggestion.icon)
+      << ", trailing_icon:"
+      << ConvertIconToPrintableString(suggestion.trailing_icon) << ")";
+}
+
 }  // namespace autofill
diff --git a/components/autofill/core/browser/ui/suggestion.h b/components/autofill/core/browser/ui/suggestion.h
index a8b9bca..fc00c69 100644
--- a/components/autofill/core/browser/ui/suggestion.h
+++ b/components/autofill/core/browser/ui/suggestion.h
@@ -9,10 +9,12 @@
 #include <string>
 
 #include "base/logging.h"
+#include "base/notreached.h"
 #include "base/strings/string_piece.h"
 #include "base/types/cxx23_to_underlying.h"
 #include "base/types/strong_alias.h"
 #include "build/build_config.h"
+#include "components/autofill/core/browser/field_types.h"
 #include "components/autofill/core/browser/ui/popup_item_ids.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
@@ -54,10 +56,13 @@
     ShouldTruncate should_truncate = ShouldTruncate(false);
   };
 
+  // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.ui.suggestion
   enum class Icon {
+    kNoIcon,
     kAccount,
     kClear,
     kCreate,
+    kCode,
     kDelete,
     kDevice,
     kEdit,
@@ -73,8 +78,10 @@
     kLocation,
     kMagic,
     kOfferTag,
+    kPenSpark,
     kScanCreditCard,
     kSettings,
+    kSettingsAndroid,
     kUndo,
     // Credit card icons
     kCardGeneric,
@@ -83,13 +90,18 @@
     kCardDiscover,
     kCardElo,
     kCardJCB,
-    kCardMaster,
+    kCardMasterCard,
     kCardMir,
     kCardTroy,
     kCardUnionPay,
     kCardVisa,
   };
 
+  // TODO(crbug.com/1019660): Remove this method, pass Suggestion::Icon from the
+  // beginning.
+  static Suggestion::Icon ConvertIconStringIntoIcon(
+      std::string_view icon_string);
+
   Suggestion();
   explicit Suggestion(std::u16string main_text);
   explicit Suggestion(PopupItemId popup_item_id);
@@ -98,12 +110,12 @@
   // UTF-16.
   Suggestion(base::StringPiece main_text,
              base::StringPiece label,
-             std::string icon,
+             Icon icon,
              PopupItemId popup_item_id);
   Suggestion(base::StringPiece main_text,
              base::StringPiece minor_text,
              base::StringPiece label,
-             std::string icon,
+             Icon icon,
              PopupItemId popup_item_id);
   Suggestion(const Suggestion& other);
   Suggestion(Suggestion&& other);
@@ -179,10 +191,9 @@
   bool is_icon_at_start = false;
 #endif  // BUILDFLAG(IS_ANDROID)
 
-  // TODO(crbug.com/1019660): Identify icons with enum instead of strings.
   // This is the icon which is shown on the side of a suggestion.
-  // If |custom_icon| is empty, the name of the fallback built-in icon.
-  std::string icon;
+  // If |custom_icon| is empty, the fallback built-in icon.
+  Icon icon = Icon::kNoIcon;
 
   // An icon that appears after the suggestion in the suggestion view. For
   // passwords, this icon string shows whether the suggestion originates from
@@ -190,7 +201,7 @@
   // credit card Autofill popup to indicate if all credit cards are server
   // cards. It also holds Google Password Manager icon on the settings entry for
   // the passwords Autofill popup.
-  std::string trailing_icon;
+  Icon trailing_icon = Icon::kNoIcon;
 
   // Whether suggestion was interacted with and is now in a loading state.
   IsLoading is_loading = IsLoading(false);
@@ -200,27 +211,19 @@
   std::string feature_for_iph;
 
   // If specified, this text will be played back as voice over for a11y.
-  absl::optional<std::u16string> voice_over;
+  std::optional<std::u16string> voice_over;
 
   // If specified, this text will be played back if the user accepts this
   // suggestion.
-  absl::optional<std::u16string> acceptance_a11y_announcement;
+  std::optional<std::u16string> acceptance_a11y_announcement;
+
+  // When `popup_item_id` is `PopupItemId::kFieldByFieldFilling`, specifies the
+  // `ServerFieldType` used to build the suggestion's `main_text`.
+  std::optional<ServerFieldType> field_by_field_filling_type_used;
 };
 
-#if defined(UNIT_TEST)
-inline void PrintTo(const Suggestion& suggestion, std::ostream* os) {
-  *os << std::endl
-      << "Suggestion (popup_item_id:"
-      << base::to_underlying(suggestion.popup_item_id) << ", main_text:\""
-      << suggestion.main_text.value << "\""
-      << (suggestion.main_text.is_primary ? "(Primary)" : "(Not Primary)")
-      << ", minor_text:\"" << suggestion.minor_text.value << "\""
-      << (suggestion.minor_text.is_primary ? "(Primary)" : "(Not Primary)")
-      << ", additional_label: \"" << suggestion.additional_label << "\""
-      << ", icon:" << suggestion.icon
-      << ", trailing_icon:" << suggestion.trailing_icon << ")";
-}
-#endif
+std::string_view ConvertIconToPrintableString(Suggestion::Icon icon);
+void PrintTo(const Suggestion& suggestion, std::ostream* os);
 
 }  // namespace autofill
 
diff --git a/components/autofill/core/browser/validation.h b/components/autofill/core/browser/validation.h
index 7036240..1fdb581 100644
--- a/components/autofill/core/browser/validation.h
+++ b/components/autofill/core/browser/validation.h
@@ -7,7 +7,7 @@
 
 #include <string>
 
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 
 namespace base {
 class Time;
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc
index 76774b26..f2a4f34a 100644
--- a/components/autofill/core/common/autofill_features.cc
+++ b/components/autofill/core/common/autofill_features.cc
@@ -435,31 +435,6 @@
 const base::FeatureParam<bool> kAutofillModelPredictionsAreActive{
     &kAutofillModelPredictions, "model_active", false};
 
-// Allows passing a set of overrides for Autofill server predictions.
-// Example command line to override server predictions manually:
-// chrome --enable-features=AutofillOverridePredictions:spec/1_2_4-7_8_9
-// This creates two manual overrides that supersede server predictions as
-// follows:
-// * The server prediction for the field with signature 2 in the form with
-//   signature 1 is overridden to be 4 (NAME_MIDDLE).
-// * The server prediction for the field with signature 8 in the form with
-//   signature 7 is overridden to be 9 (EMAIL_ADDRESS).
-//
-// See components/autofill/core/browser/server_prediction_overrides.h for more
-// examples and details on how to specify overrides.
-BASE_FEATURE(kAutofillOverridePredictions,
-             "AutofillOverridePredictions",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-// The override specification in string form.
-const base::FeatureParam<std::string> kAutofillOverridePredictionsSpecification{
-    &kAutofillOverridePredictions, "spec", "[]"};
-
-// The override specification using alternative_form_signature in string form.
-const base::FeatureParam<std::string>
-    kAutofillOverridePredictionsForAlternativeFormSignaturesSpecification{
-        &kAutofillOverridePredictions, "alternative_signature_spec", "[]"};
-
 // If enabled, Autofill will first look at field labels and then at field
 // attributes when classifying address fields in Mexico.
 BASE_FEATURE(kAutofillPreferLabelsInSomeCountries,
@@ -818,6 +793,31 @@
              "AutofillLogToTerminal",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
+// Allows passing a set of overrides for Autofill server predictions.
+// Example command line to override server predictions manually:
+// chrome --enable-features=AutofillOverridePredictions:spec/1_2_4-7_8_9
+// This creates two manual overrides that supersede server predictions as
+// follows:
+// * The server prediction for the field with signature 2 in the form with
+//   signature 1 is overridden to be 4 (NAME_MIDDLE).
+// * The server prediction for the field with signature 8 in the form with
+//   signature 7 is overridden to be 9 (EMAIL_ADDRESS).
+//
+// See components/autofill/core/browser/server_prediction_overrides.h for more
+// examples and details on how to specify overrides.
+BASE_FEATURE(kAutofillOverridePredictions,
+             "AutofillOverridePredictions",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
+// The override specification in string form.
+const base::FeatureParam<std::string> kAutofillOverridePredictionsSpecification{
+    &kAutofillOverridePredictions, "spec", "[]"};
+
+// The override specification using alternative_form_signature in string form.
+const base::FeatureParam<std::string>
+    kAutofillOverridePredictionsForAlternativeFormSignaturesSpecification{
+        &kAutofillOverridePredictions, "alternative_signature_spec", "[]"};
+
 // Enables or Disables (mostly for hermetic testing) autofill server
 // communication. The URL of the autofill server can further be controlled via
 // the autofill-server-url param. The given URL should specify the complete
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h
index b65483e..01ba23c 100644
--- a/components/autofill/core/common/autofill_features.h
+++ b/components/autofill/core/common/autofill_features.h
@@ -157,13 +157,6 @@
 extern const base::FeatureParam<std::string> kAutofillModelDictionaryFilePath;
 COMPONENT_EXPORT(AUTOFILL)
 extern const base::FeatureParam<bool> kAutofillModelPredictionsAreActive;
-COMPONENT_EXPORT(AUTOFILL) BASE_DECLARE_FEATURE(kAutofillOverridePredictions);
-COMPONENT_EXPORT(AUTOFILL)
-extern const base::FeatureParam<std::string>
-    kAutofillOverridePredictionsSpecification;
-COMPONENT_EXPORT(AUTOFILL)
-extern const base::FeatureParam<std::string>
-    kAutofillOverridePredictionsForAlternativeFormSignaturesSpecification;
 COMPONENT_EXPORT(AUTOFILL) BASE_DECLARE_FEATURE(kAutofillPageLanguageDetection);
 COMPONENT_EXPORT(AUTOFILL) BASE_DECLARE_FEATURE(kAutofillParseAsync);
 COMPONENT_EXPORT(AUTOFILL)
@@ -295,6 +288,13 @@
 COMPONENT_EXPORT(AUTOFILL)
 BASE_DECLARE_FEATURE(kAutofillDisableSilentProfileUpdates);
 COMPONENT_EXPORT(AUTOFILL) BASE_DECLARE_FEATURE(kAutofillLogToTerminal);
+COMPONENT_EXPORT(AUTOFILL) BASE_DECLARE_FEATURE(kAutofillOverridePredictions);
+COMPONENT_EXPORT(AUTOFILL)
+extern const base::FeatureParam<std::string>
+    kAutofillOverridePredictionsSpecification;
+COMPONENT_EXPORT(AUTOFILL)
+extern const base::FeatureParam<std::string>
+    kAutofillOverridePredictionsForAlternativeFormSignaturesSpecification;
 COMPONENT_EXPORT(AUTOFILL) BASE_DECLARE_FEATURE(kAutofillServerCommunication);
 COMPONENT_EXPORT(AUTOFILL) BASE_DECLARE_FEATURE(kAutofillShowTypePredictions);
 COMPONENT_EXPORT(AUTOFILL) BASE_DECLARE_FEATURE(kAutofillUploadThrottling);
diff --git a/components/autofill/ios/browser/autofill_agent.mm b/components/autofill/ios/browser/autofill_agent.mm
index 64c44f3..e642da44 100644
--- a/components/autofill/ios/browser/autofill_agent.mm
+++ b/components/autofill/ios/browser/autofill_agent.mm
@@ -713,7 +713,8 @@
                                        scale:icon.scale * ratio
                                  orientation:icon.imageOrientation];
           }
-        } else if (!popup_suggestion.icon.empty()) {
+        } else if (popup_suggestion.icon !=
+                   autofill::Suggestion::Icon::kNoIcon) {
           const int resourceID =
               autofill::CreditCard::IconResourceId(popup_suggestion.icon);
           icon = ui::ResourceBundle::GetSharedInstance()
diff --git a/components/autofill/ios/browser/autofill_agent_unittests.mm b/components/autofill/ios/browser/autofill_agent_unittests.mm
index 688502ee..b3160b1 100644
--- a/components/autofill/ios/browser/autofill_agent_unittests.mm
+++ b/components/autofill/ios/browser/autofill_agent_unittests.mm
@@ -319,7 +319,8 @@
   // Make the suggestions available to AutofillAgent.
   std::vector<autofill::Suggestion> autofillSuggestions;
   autofillSuggestions.push_back(
-      autofill::Suggestion("", "", "", PopupItemId::kShowAccountCards));
+      autofill::Suggestion("", "", autofill::Suggestion::Icon::kNoIcon,
+                           PopupItemId::kShowAccountCards));
   [autofill_agent_ showAutofillPopup:autofillSuggestions
                        popupDelegate:mock_delegate.GetWeakPtr()];
 
@@ -368,11 +369,11 @@
       .WillOnce(testing::Return(PopupType::kUnspecified));
   // Initialize suggestion.
   std::vector<autofill::Suggestion> autofillSuggestions = {
-      autofill::Suggestion("", "", "visaCC",
+      autofill::Suggestion("", "", autofill::Suggestion::Icon::kCardVisa,
                            autofill::PopupItemId::kCreditCardEntry),
       // This suggestion has a valid credit card icon, but the Suggestion type
       // (kShowAccountCards) is wrong.
-      autofill::Suggestion("", "", "visaCC",
+      autofill::Suggestion("", "", autofill::Suggestion::Icon::kCardVisa,
                            autofill::PopupItemId::kShowAccountCards),
   };
   // Completion handler to retrieve suggestions.
@@ -419,9 +420,9 @@
   EXPECT_CALL(mock_delegate, GetPopupType)
       .WillRepeatedly(testing::Return(PopupType::kCreditCards));
 
-  const std::string emptyIcon = "";
-  std::vector<autofill::Suggestion> autofillSuggestions = {autofill::Suggestion(
-      "", "", emptyIcon, autofill::PopupItemId::kCreditCardEntry)};
+  std::vector<autofill::Suggestion> autofillSuggestions = {
+      autofill::Suggestion("", "", autofill::Suggestion::Icon::kNoIcon,
+                           autofill::PopupItemId::kCreditCardEntry)};
 
   // Completion handler to retrieve suggestions.
   auto completionHandler = ^(NSArray<FormSuggestion*>* suggestions,
@@ -448,9 +449,11 @@
   const std::string createSuggestionText = "create";
   const std::string fillExistingSuggestionText = "existing";
   std::vector<autofill::Suggestion> autofillSuggestions = {
-      autofill::Suggestion(createSuggestionText, "", "",
+      autofill::Suggestion(createSuggestionText, "",
+                           autofill::Suggestion::Icon::kNoIcon,
                            autofill::PopupItemId::kCreateNewPlusAddress),
-      autofill::Suggestion(fillExistingSuggestionText, "", "",
+      autofill::Suggestion(fillExistingSuggestionText, "",
+                           autofill::Suggestion::Icon::kNoIcon,
                            autofill::PopupItemId::kFillExistingPlusAddress)};
 
   // Completion handler to retrieve suggestions.
@@ -491,7 +494,8 @@
 // icon.
 TEST_F(AutofillAgentTests,
        showAutofillPopup_PreferCustomIconForCreditCardSuggestions) {
-  const std::string suggestion_network_icon = "visaCC";
+  autofill::Suggestion::Icon suggestion_network_icon =
+      autofill::Suggestion::Icon::kCardVisa;
   UIImage* network_icon_image =
       ui::ResourceBundle::GetSharedInstance()
           .GetNativeImageNamed(
@@ -546,11 +550,13 @@
   // Make the suggestions available to AutofillAgent.
   std::vector<autofill::Suggestion> autofillSuggestions;
   autofillSuggestions.push_back(
-      autofill::Suggestion("", "", "", autofill::PopupItemId::kAddressEntry));
+      autofill::Suggestion("", "", autofill::Suggestion::Icon::kNoIcon,
+                           autofill::PopupItemId::kAddressEntry));
   autofillSuggestions.push_back(
-      autofill::Suggestion("", "", "", autofill::PopupItemId::kAddressEntry));
-  autofillSuggestions.push_back(
-      autofill::Suggestion("", "", "", PopupItemId::kClearForm));
+      autofill::Suggestion("", "", autofill::Suggestion::Icon::kNoIcon,
+                           autofill::PopupItemId::kAddressEntry));
+  autofillSuggestions.push_back(autofill::Suggestion(
+      "", "", autofill::Suggestion::Icon::kNoIcon, PopupItemId::kClearForm));
   [autofill_agent_
       showAutofillPopup:autofillSuggestions
           popupDelegate:base::WeakPtr<autofill::AutofillPopupDelegate>()];
@@ -600,12 +606,14 @@
 
   // Make the suggestions available to AutofillAgent.
   std::vector<autofill::Suggestion> autofillSuggestions;
-  autofillSuggestions.push_back(autofill::Suggestion(
-      "", "", "", autofill::PopupItemId::kCreditCardEntry));
-  autofillSuggestions.push_back(autofill::Suggestion(
-      "", "", "", autofill::PopupItemId::kCreditCardEntry));
   autofillSuggestions.push_back(
-      autofill::Suggestion("", "", "", PopupItemId::kClearForm));
+      autofill::Suggestion("", "", autofill::Suggestion::Icon::kNoIcon,
+                           autofill::PopupItemId::kCreditCardEntry));
+  autofillSuggestions.push_back(
+      autofill::Suggestion("", "", autofill::Suggestion::Icon::kNoIcon,
+                           autofill::PopupItemId::kCreditCardEntry));
+  autofillSuggestions.push_back(autofill::Suggestion(
+      "", "", autofill::Suggestion::Icon::kNoIcon, PopupItemId::kClearForm));
   [autofill_agent_
       showAutofillPopup:autofillSuggestions
           popupDelegate:base::WeakPtr<autofill::AutofillPopupDelegate>()];
diff --git a/components/autofill_payments_strings.grdp b/components/autofill_payments_strings.grdp
index 1fba98c..83d1770da 100644
--- a/components/autofill_payments_strings.grdp
+++ b/components/autofill_payments_strings.grdp
@@ -548,6 +548,12 @@
     </message>
   </if>
   <if expr="is_ios">
+    <message name="IDS_PAYMENTS_AUTOFILL_ENABLE_MANDATORY_REAUTH_TOGGLE_LABEL" desc="Label for a toggle that allows users to turn on mandatory authentication when managing credit cards. Title-Cased.">
+      Always Verify When Using Autofill
+    </message>
+    <message name="IDS_PAYMENTS_AUTOFILL_ENABLE_MANDATORY_REAUTH_TOGGLE_SUBLABEL" desc="Sublabel for a toggle that allows users to turn on mandatory authentication when managing credit cards. This sublabel explains when the toggle is turned off Autofill will still request authentication occasionally.">
+      When turned off, you may be asked occasionally to verify for security purposes
+    </message>
     <if expr="_google_chrome">
       <message name="IDS_PAYMENTS_AUTOFILL_FILLING_MANDATORY_REAUTH" desc="Text that appears in the payments autofill mandatory re-authentication popup as the sublabel, asking the user to authenticate using biometric or device unlock before filling.">
         Verify it's you so Google Chrome can fill in your payment info.
diff --git a/components/autofill_payments_strings_grdp/IDS_PAYMENTS_AUTOFILL_ENABLE_MANDATORY_REAUTH_TOGGLE_LABEL.png.sha1 b/components/autofill_payments_strings_grdp/IDS_PAYMENTS_AUTOFILL_ENABLE_MANDATORY_REAUTH_TOGGLE_LABEL.png.sha1
new file mode 100644
index 0000000..a4a0d1a
--- /dev/null
+++ b/components/autofill_payments_strings_grdp/IDS_PAYMENTS_AUTOFILL_ENABLE_MANDATORY_REAUTH_TOGGLE_LABEL.png.sha1
@@ -0,0 +1 @@
+19f24045a21940298d383d6e9c24932444c88309
\ No newline at end of file
diff --git a/components/autofill_payments_strings_grdp/IDS_PAYMENTS_AUTOFILL_ENABLE_MANDATORY_REAUTH_TOGGLE_SUBLABEL.png.sha1 b/components/autofill_payments_strings_grdp/IDS_PAYMENTS_AUTOFILL_ENABLE_MANDATORY_REAUTH_TOGGLE_SUBLABEL.png.sha1
new file mode 100644
index 0000000..dfa2e12
--- /dev/null
+++ b/components/autofill_payments_strings_grdp/IDS_PAYMENTS_AUTOFILL_ENABLE_MANDATORY_REAUTH_TOGGLE_SUBLABEL.png.sha1
@@ -0,0 +1 @@
+aa965f6b6f39926be1b4be853ad8ba288998726e
\ No newline at end of file
diff --git a/components/capture_mode/audio_capturer.cc b/components/capture_mode/audio_capturer.cc
index 14cfb17..36f1dd1f3 100644
--- a/components/capture_mode/audio_capturer.cc
+++ b/components/capture_mode/audio_capturer.cc
@@ -6,7 +6,7 @@
 
 #include "base/functional/bind.h"
 #include "base/sequence_checker.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "media/base/audio_bus.h"
 #include "services/audio/public/cpp/device_factory.h"
 
diff --git a/components/capture_mode/audio_capturer.h b/components/capture_mode/audio_capturer.h
index 9621793..5acf80c 100644
--- a/components/capture_mode/audio_capturer.h
+++ b/components/capture_mode/audio_capturer.h
@@ -9,7 +9,7 @@
 
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "components/capture_mode/capture_mode_export.h"
 #include "media/base/audio_bus.h"
diff --git a/components/cast/message_port/fuchsia/create_web_message.h b/components/cast/message_port/fuchsia/create_web_message.h
index 4460e146..f27f7dab 100644
--- a/components/cast/message_port/fuchsia/create_web_message.h
+++ b/components/cast/message_port/fuchsia/create_web_message.h
@@ -8,7 +8,7 @@
 #include <fuchsia/web/cpp/fidl.h>
 #include <memory>
 
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 
 namespace cast_api_bindings {
 
diff --git a/components/certificate_matching/certificate_principal_pattern.h b/components/certificate_matching/certificate_principal_pattern.h
index dbd9a0c..3abe3293 100644
--- a/components/certificate_matching/certificate_principal_pattern.h
+++ b/components/certificate_matching/certificate_principal_pattern.h
@@ -8,7 +8,7 @@
 #include <string>
 
 #include "base/component_export.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/values.h"
 
 namespace net {
diff --git a/components/certificate_transparency/chrome_ct_policy_enforcer.cc b/components/certificate_transparency/chrome_ct_policy_enforcer.cc
index e898f711..4ba41e0 100644
--- a/components/certificate_transparency/chrome_ct_policy_enforcer.cc
+++ b/components/certificate_transparency/chrome_ct_policy_enforcer.cc
@@ -159,15 +159,15 @@
   log_operator_history_ = std::move(log_operator_history);
 
   if (valid_google_log_for_testing_.has_value()) {
-    valid_google_log_for_testing_ = absl::nullopt;
+    valid_google_log_for_testing_ = std::nullopt;
   }
   if (disqualified_log_for_testing_.has_value()) {
-    disqualified_log_for_testing_ = absl::nullopt;
+    disqualified_log_for_testing_ = std::nullopt;
   }
 }
 
 bool ChromeCTPolicyEnforcer::IsLogDisqualified(
-    base::StringPiece log_id,
+    std::string_view log_id,
     base::Time* disqualification_date) const {
   CHECK_EQ(log_id.size(), crypto::kSHA256Length);
 
@@ -179,7 +179,7 @@
 
   auto p = std::lower_bound(
       std::begin(disqualified_logs_), std::end(disqualified_logs_), log_id,
-      [](const auto& a, base::StringPiece b) { return a.first < b; });
+      [](const auto& a, std::string_view b) { return a.first < b; });
   if (p == std::end(disqualified_logs_) || p->first != log_id) {
     return false;
   }
@@ -191,7 +191,7 @@
 }
 
 bool ChromeCTPolicyEnforcer::IsLogOperatedByGoogle(
-    base::StringPiece log_id) const {
+    std::string_view log_id) const {
   if (valid_google_log_for_testing_.has_value() &&
       log_id == valid_google_log_for_testing_.value()) {
     return true;
@@ -260,7 +260,7 @@
   bool has_embedded_google_sct = false;
   bool has_embedded_nongoogle_sct = false;
   bool has_diverse_log_operators = false;
-  std::vector<base::StringPiece> embedded_log_ids;
+  std::vector<std::string_view> embedded_log_ids;
   std::string first_seen_operator;
   for (const auto& sct : verified_scts) {
     base::Time disqualification_date;
diff --git a/components/certificate_transparency/chrome_ct_policy_enforcer.h b/components/certificate_transparency/chrome_ct_policy_enforcer.h
index ac76152a..998907ced 100644
--- a/components/certificate_transparency/chrome_ct_policy_enforcer.h
+++ b/components/certificate_transparency/chrome_ct_policy_enforcer.h
@@ -6,7 +6,9 @@
 #define COMPONENTS_CERTIFICATE_TRANSPARENCY_CHROME_CT_POLICY_ENFORCER_H_
 
 #include <map>
+#include <optional>
 #include <string>
+#include <string_view>
 #include <utility>
 #include <vector>
 
@@ -16,7 +18,6 @@
 #include "base/time/clock.h"
 #include "base/time/time.h"
 #include "net/cert/ct_policy_enforcer.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace certificate_transparency {
 
@@ -119,12 +120,12 @@
   // |*disqualification_date| to the date of disqualification. Any SCTs that
   // are embedded in certificates issued after |*disqualification_date| should
   // not be trusted, nor contribute to any uniqueness or freshness
-  bool IsLogDisqualified(base::StringPiece log_id,
+  bool IsLogDisqualified(std::string_view log_id,
                          base::Time* disqualification_date) const;
 
   // Returns true if the log identified by |log_id| (the SHA-256 hash of the
   // log's DER-encoded SPKI) is operated by Google.
-  bool IsLogOperatedByGoogle(base::StringPiece log_id) const;
+  bool IsLogOperatedByGoogle(std::string_view log_id) const;
 
   // Returns true if the supplied log data are fresh enough.
   bool IsLogDataTimely() const;
@@ -155,12 +156,12 @@
 
   // If set, this log ID will be considered a valid, Google operated log.
   // Calling UpdateCTLogList clears this value if set.
-  absl::optional<std::string> valid_google_log_for_testing_;
+  std::optional<std::string> valid_google_log_for_testing_;
 
   // If set, this log ID will be considered a disqualified log, effective at the
   // specified time.
   // Calling UpdateCTLogList clears this value if set.
-  absl::optional<std::pair<std::string, base::Time>>
+  std::optional<std::pair<std::string, base::Time>>
       disqualified_log_for_testing_;
 };
 
diff --git a/components/cloud_devices/common/cloud_device_description.h b/components/cloud_devices/common/cloud_device_description.h
index 1f41ec1..5f0b72b 100644
--- a/components/cloud_devices/common/cloud_device_description.h
+++ b/components/cloud_devices/common/cloud_device_description.h
@@ -8,7 +8,7 @@
 #include <memory>
 #include <string>
 
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/values.h"
 
 namespace cloud_devices {
diff --git a/components/content_settings/core/common/content_settings_pattern.h b/components/content_settings/core/common/content_settings_pattern.h
index a15ff86e..becf8848 100644
--- a/components/content_settings/core/common/content_settings_pattern.h
+++ b/components/content_settings/core/common/content_settings_pattern.h
@@ -11,7 +11,7 @@
 #include <string>
 
 #include "base/gtest_prod_util.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "mojo/public/cpp/bindings/struct_traits.h"
 
 class GURL;
diff --git a/components/content_settings/core/common/content_settings_pattern_parser.h b/components/content_settings/core/common/content_settings_pattern_parser.h
index 63cef482..6f49816 100644
--- a/components/content_settings/core/common/content_settings_pattern_parser.h
+++ b/components/content_settings/core/common/content_settings_pattern_parser.h
@@ -7,7 +7,7 @@
 
 #include <string>
 
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "components/content_settings/core/common/content_settings_pattern.h"
 
 class GURL;
diff --git a/components/content_settings/renderer/content_settings_agent_impl_browsertest.cc b/components/content_settings/renderer/content_settings_agent_impl_browsertest.cc
index 62c76cc3..f832595 100644
--- a/components/content_settings/renderer/content_settings_agent_impl_browsertest.cc
+++ b/components/content_settings/renderer/content_settings_agent_impl_browsertest.cc
@@ -8,6 +8,7 @@
 #include "base/functional/callback_helpers.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/values.h"
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/content_settings/core/common/content_settings_utils.h"
@@ -20,6 +21,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
 #include "third_party/blink/public/common/browser_interface_broker_proxy.h"
+#include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/navigation/navigation_params.h"
 #include "third_party/blink/public/mojom/loader/code_cache.mojom.h"
 #include "third_party/blink/public/platform/web_url.h"
@@ -174,9 +176,25 @@
 
 }  // namespace
 
-class ContentSettingsAgentImplBrowserTest : public content::RenderViewTest {
+enum class BackgroundResourceFetchTestCase {
+  kBackgroundResourceFetchEnabled,
+  kBackgroundResourceFetchDisabled,
+};
+
+class ContentSettingsAgentImplBrowserTest
+    : public content::RenderViewTest,
+      public testing::WithParamInterface<BackgroundResourceFetchTestCase> {
  protected:
   void SetUp() override {
+    std::vector<base::test::FeatureRef> enabled_features;
+    std::vector<base::test::FeatureRef> disabled_features;
+    if (IsBackgroundResourceFetchEnabled()) {
+      enabled_features.push_back(blink::features::kBackgroundResourceFetch);
+    } else {
+      disabled_features.push_back(blink::features::kBackgroundResourceFetch);
+    }
+    feature_background_resource_fetch_.InitWithFeatures(enabled_features,
+                                                        disabled_features);
     RenderViewTest::SetUp();
 
     // Set up a fake url loader factory to ensure that script loader can create
@@ -227,15 +245,37 @@
     mojo::Receiver<blink::mojom::CodeCacheHost> receiver_{this};
   };
 
-  void OnCodeCacheHostRequest(mojo::ScopedMessagePipeHandle handle) {
-    fake_code_cache_host_ = std::make_unique<FakeCodeCacheHost>(
-        mojo::PendingReceiver<blink::mojom::CodeCacheHost>(std::move(handle)));
+  bool IsBackgroundResourceFetchEnabled() const {
+    return GetParam() ==
+           BackgroundResourceFetchTestCase::kBackgroundResourceFetchEnabled;
   }
 
-  std::unique_ptr<FakeCodeCacheHost> fake_code_cache_host_;
+  void OnCodeCacheHostRequest(mojo::ScopedMessagePipeHandle handle) {
+    fake_code_cache_hosts_.emplace_back(std::make_unique<FakeCodeCacheHost>(
+        mojo::PendingReceiver<blink::mojom::CodeCacheHost>(std::move(handle))));
+  }
+
+  std::vector<std::unique_ptr<FakeCodeCacheHost>> fake_code_cache_hosts_;
+  base::test::ScopedFeatureList feature_background_resource_fetch_;
 };
 
-TEST_F(ContentSettingsAgentImplBrowserTest, AllowlistedSchemes) {
+INSTANTIATE_TEST_SUITE_P(
+    All,
+    ContentSettingsAgentImplBrowserTest,
+    testing::ValuesIn(
+        {BackgroundResourceFetchTestCase::kBackgroundResourceFetchEnabled,
+         BackgroundResourceFetchTestCase::kBackgroundResourceFetchDisabled}),
+    [](const testing::TestParamInfo<BackgroundResourceFetchTestCase>& info) {
+      switch (info.param) {
+        case (BackgroundResourceFetchTestCase::kBackgroundResourceFetchEnabled):
+          return "BackgroundResourceFetchEnabled";
+        case (
+            BackgroundResourceFetchTestCase::kBackgroundResourceFetchDisabled):
+          return "BackgroundResourceFetchDisabled";
+      }
+    });
+
+TEST_P(ContentSettingsAgentImplBrowserTest, AllowlistedSchemes) {
   url::ScopedSchemeRegistryForTests scoped_registry;
   url::AddStandardScheme(kAllowlistScheme, url::SCHEME_WITH_HOST);
 
@@ -263,7 +303,7 @@
   EXPECT_FALSE(mock_agent.IsAllowlistedForContentSettings());
 }
 
-TEST_F(ContentSettingsAgentImplBrowserTest, DidBlockContentType) {
+TEST_P(ContentSettingsAgentImplBrowserTest, DidBlockContentType) {
   MockContentSettingsAgentImpl mock_agent(GetMainRenderFrame());
   mock_agent.DidBlockContentType(ContentSettingsType::COOKIES);
   base::RunLoop().RunUntilIdle();
@@ -278,7 +318,7 @@
 
 // Tests that multiple invocations of AllowStorageAccessSync result in a single
 // IPC.
-TEST_F(ContentSettingsAgentImplBrowserTest, AllowStorageAccessSync) {
+TEST_P(ContentSettingsAgentImplBrowserTest, AllowStorageAccessSync) {
   // Load some HTML, so we have a valid security origin.
   LoadHTMLWithUrlOverride("<html></html>", "https://example.com/");
   MockContentSettingsAgentImpl mock_agent(GetMainRenderFrame());
@@ -296,7 +336,7 @@
 }
 
 // Tests that multiple invocations of AllowStorageAccess result in a single IPC.
-TEST_F(ContentSettingsAgentImplBrowserTest, AllowStorageAccess) {
+TEST_P(ContentSettingsAgentImplBrowserTest, AllowStorageAccess) {
   // Load some HTML, so we have a valid security origin.
   LoadHTMLWithUrlOverride("<html></html>", "https://example.com/");
   MockContentSettingsAgentImpl mock_agent(GetMainRenderFrame());
@@ -315,7 +355,7 @@
   EXPECT_EQ(1, mock_agent.allow_storage_access_count());
 }
 
-TEST_F(ContentSettingsAgentImplBrowserTest, ImagesBlockedByDefault) {
+TEST_P(ContentSettingsAgentImplBrowserTest, ImagesBlockedByDefault) {
   MockContentSettingsAgentImpl mock_agent(GetMainRenderFrame());
 
   // Load some HTML.
@@ -353,7 +393,7 @@
   EXPECT_EQ(1, mock_agent.on_content_blocked_count());
 }
 
-TEST_F(ContentSettingsAgentImplBrowserTest, ImagesAllowedByDefault) {
+TEST_P(ContentSettingsAgentImplBrowserTest, ImagesAllowedByDefault) {
   MockContentSettingsAgentImpl mock_agent(GetMainRenderFrame());
 
   // Load some HTML.
@@ -390,7 +430,7 @@
   EXPECT_EQ(ContentSettingsType::IMAGES, mock_agent.on_content_blocked_type());
 }
 
-TEST_F(ContentSettingsAgentImplBrowserTest, ContentSettingsBlockScripts) {
+TEST_P(ContentSettingsAgentImplBrowserTest, ContentSettingsBlockScripts) {
   MockContentSettingsAgentImpl mock_agent(GetMainRenderFrame());
   // Set the content settings for scripts.
   RendererContentSettingRules content_setting_rules;
@@ -412,7 +452,7 @@
   EXPECT_EQ(1, mock_agent.on_content_blocked_count());
 }
 
-TEST_F(ContentSettingsAgentImplBrowserTest,
+TEST_P(ContentSettingsAgentImplBrowserTest,
        ContentSettingsAllowScriptsWithSrc) {
   MockContentSettingsAgentImpl mock_agent(GetMainRenderFrame());
   // Set the content settings for scripts.
@@ -435,7 +475,7 @@
   EXPECT_EQ(0, mock_agent.on_content_blocked_count());
 }
 
-TEST_F(ContentSettingsAgentImplBrowserTest, MixedAutoupgradesDisabledByRules) {
+TEST_P(ContentSettingsAgentImplBrowserTest, MixedAutoupgradesDisabledByRules) {
   MockContentSettingsAgentImpl mock_agent(GetMainRenderFrame());
 
   LoadHTMLWithUrlOverride("<html></html>", "https://example.com/");
@@ -467,7 +507,7 @@
   EXPECT_FALSE(agent->ShouldAutoupgradeMixedContent());
 }
 
-TEST_F(ContentSettingsAgentImplBrowserTest, MixedAutoupgradesNoSettingsSet) {
+TEST_P(ContentSettingsAgentImplBrowserTest, MixedAutoupgradesNoSettingsSet) {
   MockContentSettingsAgentImpl mock_agent(GetMainRenderFrame());
 
   ContentSettingsAgentImpl* agent =
@@ -475,7 +515,7 @@
   EXPECT_TRUE(agent->ShouldAutoupgradeMixedContent());
 }
 
-TEST_F(ContentSettingsAgentImplBrowserTest, ContentSettingsAllowedAutoDark) {
+TEST_P(ContentSettingsAgentImplBrowserTest, ContentSettingsAllowedAutoDark) {
   MockContentSettingsAgentImpl mock_agent(GetMainRenderFrame());
 
   // Load some HTML.
@@ -507,7 +547,7 @@
   EXPECT_FALSE(agent->AllowAutoDarkWebContent(true));
 }
 
-TEST_F(ContentSettingsAgentImplBrowserTest, ContentSettingsDisabledAutoDark) {
+TEST_P(ContentSettingsAgentImplBrowserTest, ContentSettingsDisabledAutoDark) {
   MockContentSettingsAgentImpl mock_agent(GetMainRenderFrame());
 
   // Load some HTML.
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn
index 9fff8d1d..0ff70af 100644
--- a/components/cronet/android/BUILD.gn
+++ b/components/cronet/android/BUILD.gn
@@ -1748,6 +1748,9 @@
 copy("cronet_package_copy_test_files") {
   testonly = true
   sources = [
+    "//net/data/ssl/certificates/cronet-quic-chain.pem",
+    "//net/data/ssl/certificates/cronet-quic-leaf-cert.key",
+    "//net/data/ssl/certificates/cronet-quic-leaf-cert.key.pkcs8.pem",
     "//net/data/ssl/certificates/expired_cert.pem",
     "//net/data/ssl/certificates/quic-chain.pem",
     "//net/data/ssl/certificates/quic-leaf-cert.key",
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/AndroidBidirectionalStreamBuilderWrapper.java b/components/cronet/android/java/src/org/chromium/net/impl/AndroidBidirectionalStreamBuilderWrapper.java
index 41f0bd2..df93de13 100644
--- a/components/cronet/android/java/src/org/chromium/net/impl/AndroidBidirectionalStreamBuilderWrapper.java
+++ b/components/cronet/android/java/src/org/chromium/net/impl/AndroidBidirectionalStreamBuilderWrapper.java
@@ -4,8 +4,12 @@
 
 package org.chromium.net.impl;
 
+import android.net.Network;
+
 import androidx.annotation.RequiresApi;
 
+import org.chromium.net.CronetEngine;
+
 @RequiresApi(api = 34)
 class AndroidBidirectionalStreamBuilderWrapper
         extends org.chromium.net.ExperimentalBidirectionalStream.Builder {
@@ -36,6 +40,20 @@
     }
 
     @Override
+    public org.chromium.net.ExperimentalBidirectionalStream.Builder bindToNetwork(
+            long networkHandle) {
+        // Network#fromNetworkHandle throws IAE if networkHandle does not translate to a valid
+        // Network. Though, this can only happen if we're given a fake networkHandle (in which case
+        // we will throw, which is fine).
+        Network network =
+                networkHandle == CronetEngine.UNBIND_NETWORK_HANDLE
+                        ? null
+                        : Network.fromNetworkHandle(networkHandle);
+        // TODO(b/309112420): Stop no-op'ing this.
+        return this;
+    }
+
+    @Override
     public org.chromium.net.ExperimentalBidirectionalStream.Builder
     delayRequestHeadersUntilFirstFlush(boolean delayRequestHeadersUntilFirstFlush) {
         mBackend.setDelayRequestHeadersUntilFirstFlushEnabled(delayRequestHeadersUntilFirstFlush);
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/AndroidHttpEngineWrapper.java b/components/cronet/android/java/src/org/chromium/net/impl/AndroidHttpEngineWrapper.java
index e4a1ff2..1f9c271 100644
--- a/components/cronet/android/java/src/org/chromium/net/impl/AndroidHttpEngineWrapper.java
+++ b/components/cronet/android/java/src/org/chromium/net/impl/AndroidHttpEngineWrapper.java
@@ -4,6 +4,7 @@
 
 package org.chromium.net.impl;
 
+import android.net.Network;
 import android.net.http.HttpEngine;
 
 import androidx.annotation.RequiresApi;
@@ -52,6 +53,18 @@
     }
 
     @Override
+    public void bindToNetwork(long networkHandle) {
+        // Network#fromNetworkHandle throws IAE if networkHandle does not translate to a valid
+        // Network. Though, this can only happen if we're given a fake networkHandle (in which case
+        // we will throw, which is fine).
+        Network network =
+                networkHandle == UNBIND_NETWORK_HANDLE
+                        ? null
+                        : Network.fromNetworkHandle(networkHandle);
+        mBackend.bindToNetwork(network);
+    }
+
+    @Override
     public URLConnection openConnection(URL url) throws IOException {
         return CronetExceptionTranslationUtils.executeTranslatingCronetExceptions(
                 () -> mBackend.openConnection(url), IOException.class);
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/AndroidUrlRequestBuilderWrapper.java b/components/cronet/android/java/src/org/chromium/net/impl/AndroidUrlRequestBuilderWrapper.java
index e95c37e..b7313c5e 100644
--- a/components/cronet/android/java/src/org/chromium/net/impl/AndroidUrlRequestBuilderWrapper.java
+++ b/components/cronet/android/java/src/org/chromium/net/impl/AndroidUrlRequestBuilderWrapper.java
@@ -4,8 +4,12 @@
 
 package org.chromium.net.impl;
 
+import android.net.Network;
+
 import androidx.annotation.RequiresApi;
 
+import org.chromium.net.CronetEngine;
+
 import java.util.concurrent.Executor;
 
 @RequiresApi(api = 34)
@@ -54,6 +58,19 @@
     }
 
     @Override
+    public org.chromium.net.ExperimentalUrlRequest.Builder bindToNetwork(long networkHandle) {
+        // Network#fromNetworkHandle throws IAE if networkHandle does not translate to a valid
+        // Network. Though, this can only happen if we're given a fake networkHandle (in which case
+        // we will throw, which is fine).
+        Network network =
+                networkHandle == CronetEngine.UNBIND_NETWORK_HANDLE
+                        ? null
+                        : Network.fromNetworkHandle(networkHandle);
+        mBackend.bindToNetwork(network);
+        return this;
+    }
+
+    @Override
     public org.chromium.net.ExperimentalUrlRequest build() {
         return new AndroidUrlRequestWrapper(mBackend.build());
     }
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/AndroidUrlResponseInfoWrapper.java b/components/cronet/android/java/src/org/chromium/net/impl/AndroidUrlResponseInfoWrapper.java
index da48de06..07476ee 100644
--- a/components/cronet/android/java/src/org/chromium/net/impl/AndroidUrlResponseInfoWrapper.java
+++ b/components/cronet/android/java/src/org/chromium/net/impl/AndroidUrlResponseInfoWrapper.java
@@ -12,9 +12,35 @@
 @RequiresApi(api = 34)
 class AndroidUrlResponseInfoWrapper extends org.chromium.net.UrlResponseInfo {
     private final android.net.http.UrlResponseInfo mBackend;
+    /* org.chromium.net.UrlRequest and org.chromium.net.BidirectionalStream map the direct or
+     * no-proxy scenarios to different values of org.chromium.net.UrlResponseInfo#getProxyServer:
+     * UrlRequest will return ":0", while BidirectionalStream will return a null string.
+     * This variable is needed to maintain compatibility with this non-documented behavior, as
+     * android.net.http.UrlResponseInfo doesn't expose a getProxyServer method.
+     * TODO(b/309121551): Clean this up.
+     */
+    private final String mProxyServerCompat;
 
-    AndroidUrlResponseInfoWrapper(android.net.http.UrlResponseInfo backend) {
+    private AndroidUrlResponseInfoWrapper(
+            android.net.http.UrlResponseInfo backend, String proxyServerCompat) {
         this.mBackend = backend;
+        this.mProxyServerCompat = proxyServerCompat;
+    }
+
+    // See mProxyServerCompat's Javadoc.
+    public static AndroidUrlResponseInfoWrapper createForUrlRequest(
+            android.net.http.UrlResponseInfo backend) {
+        // From //components/cronet/cronet_url_request.cc's GetProxy.
+        return new AndroidUrlResponseInfoWrapper(backend, ":0");
+    }
+
+    // See mProxyServerCompat's Javadoc.
+    public static AndroidUrlResponseInfoWrapper createForBidirectionalStream(
+            android.net.http.UrlResponseInfo backend) {
+        // From
+        // //components/cronet/android/java/src/org/chromium/net/impl/CronetBidirectionalStream.java
+        // prepareResponseInfoOnNetworkThread.
+        return new AndroidUrlResponseInfoWrapper(backend, null);
     }
 
     @Override
@@ -59,7 +85,7 @@
 
     @Override
     public String getProxyServer() {
-        return null;
+        return mProxyServerCompat;
     }
 
     @Override
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/BidirectionalStreamCallbackWrapper.java b/components/cronet/android/java/src/org/chromium/net/impl/BidirectionalStreamCallbackWrapper.java
index 90bfcd0..c0d23652 100644
--- a/components/cronet/android/java/src/org/chromium/net/impl/BidirectionalStreamCallbackWrapper.java
+++ b/components/cronet/android/java/src/org/chromium/net/impl/BidirectionalStreamCallbackWrapper.java
@@ -33,7 +33,7 @@
     public void onResponseHeadersReceived(android.net.http.BidirectionalStream bidirectionalStream,
             android.net.http.UrlResponseInfo urlResponseInfo) {
         AndroidUrlResponseInfoWrapper specializedResponseInfo =
-                new AndroidUrlResponseInfoWrapper(urlResponseInfo);
+                AndroidUrlResponseInfoWrapper.createForBidirectionalStream(urlResponseInfo);
         AndroidBidirectionalStreamWrapper specializedStream =
                 new AndroidBidirectionalStreamWrapper(bidirectionalStream);
         mBackend.onResponseHeadersReceived(specializedStream, specializedResponseInfo);
@@ -44,7 +44,7 @@
             android.net.http.UrlResponseInfo urlResponseInfo, ByteBuffer byteBuffer,
             boolean endOfStream) {
         AndroidUrlResponseInfoWrapper specializedResponseInfo =
-                new AndroidUrlResponseInfoWrapper(urlResponseInfo);
+                AndroidUrlResponseInfoWrapper.createForBidirectionalStream(urlResponseInfo);
         AndroidBidirectionalStreamWrapper specializedStream =
                 new AndroidBidirectionalStreamWrapper(bidirectionalStream);
         mBackend.onReadCompleted(
@@ -56,7 +56,7 @@
             android.net.http.UrlResponseInfo urlResponseInfo, ByteBuffer byteBuffer,
             boolean endOfStream) {
         AndroidUrlResponseInfoWrapper specializedResponseInfo =
-                new AndroidUrlResponseInfoWrapper(urlResponseInfo);
+                AndroidUrlResponseInfoWrapper.createForBidirectionalStream(urlResponseInfo);
         AndroidBidirectionalStreamWrapper specializedStream =
                 new AndroidBidirectionalStreamWrapper(bidirectionalStream);
         mBackend.onWriteCompleted(
@@ -69,7 +69,7 @@
             @NonNull android.net.http.UrlResponseInfo urlResponseInfo,
             @NonNull android.net.http.HeaderBlock headerBlock) {
         AndroidUrlResponseInfoWrapper specializedResponseInfo =
-                new AndroidUrlResponseInfoWrapper(urlResponseInfo);
+                AndroidUrlResponseInfoWrapper.createForBidirectionalStream(urlResponseInfo);
         AndroidBidirectionalStreamWrapper specializedStream =
                 new AndroidBidirectionalStreamWrapper(bidirectionalStream);
         AndroidHeaderBlockWrapper specializedHeaderBlock =
@@ -82,7 +82,7 @@
     public void onSucceeded(android.net.http.BidirectionalStream bidirectionalStream,
             android.net.http.UrlResponseInfo urlResponseInfo) {
         AndroidUrlResponseInfoWrapper specializedResponseInfo =
-                new AndroidUrlResponseInfoWrapper(urlResponseInfo);
+                AndroidUrlResponseInfoWrapper.createForBidirectionalStream(urlResponseInfo);
         AndroidBidirectionalStreamWrapper specializedStream =
                 new AndroidBidirectionalStreamWrapper(bidirectionalStream);
         mBackend.onSucceeded(specializedStream, specializedResponseInfo);
@@ -92,7 +92,7 @@
     public void onFailed(android.net.http.BidirectionalStream bidirectionalStream,
             android.net.http.UrlResponseInfo urlResponseInfo, HttpException e) {
         AndroidUrlResponseInfoWrapper specializedResponseInfo =
-                new AndroidUrlResponseInfoWrapper(urlResponseInfo);
+                AndroidUrlResponseInfoWrapper.createForBidirectionalStream(urlResponseInfo);
         AndroidBidirectionalStreamWrapper specializedStream =
                 new AndroidBidirectionalStreamWrapper(bidirectionalStream);
         mBackend.onFailed(specializedStream, specializedResponseInfo,
@@ -103,7 +103,7 @@
     public void onCanceled(@NonNull android.net.http.BidirectionalStream bidirectionalStream,
             @Nullable android.net.http.UrlResponseInfo urlResponseInfo) {
         AndroidUrlResponseInfoWrapper specializedResponseInfo =
-                new AndroidUrlResponseInfoWrapper(urlResponseInfo);
+                AndroidUrlResponseInfoWrapper.createForBidirectionalStream(urlResponseInfo);
         AndroidBidirectionalStreamWrapper specializedStream =
                 new AndroidBidirectionalStreamWrapper(bidirectionalStream);
         mBackend.onCanceled(specializedStream, specializedResponseInfo);
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/CronetExceptionTranslationUtils.java b/components/cronet/android/java/src/org/chromium/net/impl/CronetExceptionTranslationUtils.java
index 02852d1..21dd726 100644
--- a/components/cronet/android/java/src/org/chromium/net/impl/CronetExceptionTranslationUtils.java
+++ b/components/cronet/android/java/src/org/chromium/net/impl/CronetExceptionTranslationUtils.java
@@ -25,7 +25,7 @@
             } else if (nonCronetException.isInstance(e)) {
                 throw (E) e;
             } else {
-                throw new AssertionError("Unexpected exception", e);
+                throw e;
             }
         }
     }
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/UrlRequestCallbackWrapper.java b/components/cronet/android/java/src/org/chromium/net/impl/UrlRequestCallbackWrapper.java
index d909e392..40d2ade 100644
--- a/components/cronet/android/java/src/org/chromium/net/impl/UrlRequestCallbackWrapper.java
+++ b/components/cronet/android/java/src/org/chromium/net/impl/UrlRequestCallbackWrapper.java
@@ -29,45 +29,55 @@
     @Override
     public void onRedirectReceived(android.net.http.UrlRequest request,
             android.net.http.UrlResponseInfo info, String newLocationUrl) throws Exception {
-        CronetExceptionTranslationUtils.executeTranslatingCronetExceptions(() -> {
-            AndroidUrlResponseInfoWrapper specializedResponseInfo =
-                    new AndroidUrlResponseInfoWrapper(info);
-            AndroidUrlRequestWrapper specializedRequest = new AndroidUrlRequestWrapper(request);
-            mBackend.onRedirectReceived(
-                    specializedRequest, specializedResponseInfo, newLocationUrl);
-            return null;
-        }, Exception.class);
+        CronetExceptionTranslationUtils.executeTranslatingCronetExceptions(
+                () -> {
+                    AndroidUrlResponseInfoWrapper specializedResponseInfo =
+                            AndroidUrlResponseInfoWrapper.createForUrlRequest(info);
+                    AndroidUrlRequestWrapper specializedRequest =
+                            new AndroidUrlRequestWrapper(request);
+                    mBackend.onRedirectReceived(
+                            specializedRequest, specializedResponseInfo, newLocationUrl);
+                    return null;
+                },
+                Exception.class);
     }
 
     @Override
     public void onResponseStarted(android.net.http.UrlRequest request,
             android.net.http.UrlResponseInfo info) throws Exception {
-        CronetExceptionTranslationUtils.executeTranslatingCronetExceptions(() -> {
-            AndroidUrlResponseInfoWrapper specializedResponseInfo =
-                    new AndroidUrlResponseInfoWrapper(info);
-            AndroidUrlRequestWrapper specializedRequest = new AndroidUrlRequestWrapper(request);
-            mBackend.onResponseStarted(specializedRequest, specializedResponseInfo);
-            return null;
-        }, Exception.class);
+        CronetExceptionTranslationUtils.executeTranslatingCronetExceptions(
+                () -> {
+                    AndroidUrlResponseInfoWrapper specializedResponseInfo =
+                            AndroidUrlResponseInfoWrapper.createForUrlRequest(info);
+                    AndroidUrlRequestWrapper specializedRequest =
+                            new AndroidUrlRequestWrapper(request);
+                    mBackend.onResponseStarted(specializedRequest, specializedResponseInfo);
+                    return null;
+                },
+                Exception.class);
     }
 
     @Override
     public void onReadCompleted(android.net.http.UrlRequest request,
             android.net.http.UrlResponseInfo info, ByteBuffer byteBuffer) throws Exception {
-        CronetExceptionTranslationUtils.executeTranslatingCronetExceptions(() -> {
-            AndroidUrlResponseInfoWrapper specializedResponseInfo =
-                    new AndroidUrlResponseInfoWrapper(info);
-            AndroidUrlRequestWrapper specializedRequest = new AndroidUrlRequestWrapper(request);
-            mBackend.onReadCompleted(specializedRequest, specializedResponseInfo, byteBuffer);
-            return null;
-        }, Exception.class);
+        CronetExceptionTranslationUtils.executeTranslatingCronetExceptions(
+                () -> {
+                    AndroidUrlResponseInfoWrapper specializedResponseInfo =
+                            AndroidUrlResponseInfoWrapper.createForUrlRequest(info);
+                    AndroidUrlRequestWrapper specializedRequest =
+                            new AndroidUrlRequestWrapper(request);
+                    mBackend.onReadCompleted(
+                            specializedRequest, specializedResponseInfo, byteBuffer);
+                    return null;
+                },
+                Exception.class);
     }
 
     @Override
     public void onSucceeded(
             android.net.http.UrlRequest request, android.net.http.UrlResponseInfo info) {
         AndroidUrlResponseInfoWrapper specializedResponseInfo =
-                new AndroidUrlResponseInfoWrapper(info);
+                AndroidUrlResponseInfoWrapper.createForUrlRequest(info);
         AndroidUrlRequestWrapper specializedRequest = new AndroidUrlRequestWrapper(request);
         mBackend.onSucceeded(specializedRequest, specializedResponseInfo);
     }
@@ -76,7 +86,7 @@
     public void onFailed(android.net.http.UrlRequest request, android.net.http.UrlResponseInfo info,
             HttpException error) {
         AndroidUrlResponseInfoWrapper specializedResponseInfo =
-                new AndroidUrlResponseInfoWrapper(info);
+                AndroidUrlResponseInfoWrapper.createForUrlRequest(info);
         AndroidUrlRequestWrapper specializedRequest = new AndroidUrlRequestWrapper(request);
         mBackend.onFailed(specializedRequest, specializedResponseInfo,
                 CronetExceptionTranslationUtils.translateCheckedAndroidCronetException(error));
@@ -86,7 +96,7 @@
     public void onCanceled(@NonNull android.net.http.UrlRequest request,
             @Nullable android.net.http.UrlResponseInfo info) {
         AndroidUrlResponseInfoWrapper specializedResponseInfo =
-                new AndroidUrlResponseInfoWrapper(info);
+                AndroidUrlResponseInfoWrapper.createForUrlRequest(info);
         AndroidUrlRequestWrapper specializedRequest = new AndroidUrlRequestWrapper(request);
         mBackend.onCanceled(specializedRequest, specializedResponseInfo);
     }
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamTest.java
index 7e4967cc..90be917 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamTest.java
@@ -5,11 +5,13 @@
 package org.chromium.net;
 
 import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.TruthJUnit.assume;
 
 import static org.junit.Assert.assertThrows;
 
 import static org.chromium.net.truth.UrlResponseInfoSubject.assertThat;
 
+import android.net.Network;
 import android.os.Build;
 import android.os.ConditionVariable;
 import android.os.Process;
@@ -29,10 +31,13 @@
 import org.chromium.net.CronetTestRule.IgnoreFor;
 import org.chromium.net.CronetTestRule.RequiresMinAndroidApi;
 import org.chromium.net.CronetTestRule.RequiresMinApi;
+import org.chromium.net.NetworkChangeNotifierAutoDetect.ConnectivityManagerDelegate;
 import org.chromium.net.TestBidirectionalStreamCallback.FailureType;
 import org.chromium.net.TestBidirectionalStreamCallback.ResponseStep;
 import org.chromium.net.impl.BidirectionalStreamNetworkException;
 import org.chromium.net.impl.CronetBidirectionalStream;
+import org.chromium.net.impl.CronetExceptionImpl;
+import org.chromium.net.impl.NetworkExceptionImpl;
 import org.chromium.net.impl.UrlResponseInfoImpl;
 
 import java.nio.ByteBuffer;
@@ -1800,6 +1805,68 @@
         assertThat(CronetTestUtil.nativeGetTaggedBytes(tag)).isGreaterThan(priorBytes);
     }
 
+    @Test
+    @RequiresMinAndroidApi(Build.VERSION_CODES.M)
+    public void testBindToInvalidNetworkFails() {
+        String url = Http2TestServer.getEchoMethodUrl();
+        TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCallback();
+
+        BidirectionalStream.Builder builder =
+                mCronetEngine
+                        .newBidirectionalStreamBuilder(url, callback, callback.getExecutor())
+                        .setHttpMethod("GET");
+
+        if (mTestRule.implementationUnderTest() == CronetImplementation.AOSP_PLATFORM) {
+            // android.net.http.UrlRequestBuilder#bindToNetwork requires an android.net.Network
+            // object. So, in this case, it
+            // will be the wrapper layer that will fail to translate that to a Network, not
+            // something in net's code. Hence, the failure will manifest itself at bind time, not at
+            // request execution time.
+            // Note: this will never happen in prod, as translation failure can only happen if we're
+            // given a fake networkHandle.
+            assertThrows(
+                    IllegalArgumentException.class,
+                    () -> builder.bindToNetwork(-150 /* invalid network handle */));
+            return;
+        }
+
+        builder.bindToNetwork(-150 /* invalid network handle */);
+        BidirectionalStream stream = builder.build();
+        stream.start();
+
+        callback.blockForDone();
+
+        assertThat(callback.mError).isNotNull();
+        if (mTestRule.implementationUnderTest() == CronetImplementation.FALLBACK) {
+            assertThat(callback.mError).isInstanceOf(CronetExceptionImpl.class);
+            assertThat(callback.mError).hasCauseThat().isInstanceOf(NetworkExceptionImpl.class);
+        } else {
+            assertThat(callback.mError).isInstanceOf(NetworkExceptionImpl.class);
+        }
+    }
+
+    @Test
+    @RequiresMinAndroidApi(Build.VERSION_CODES.M)
+    public void testBindToDefaultNetworkSucceeds() {
+        ConnectivityManagerDelegate delegate =
+                new ConnectivityManagerDelegate(mTestRule.getTestFramework().getContext());
+        Network defaultNetwork = delegate.getDefaultNetwork();
+        assume().that(defaultNetwork).isNotNull();
+
+        String url = Http2TestServer.getEchoMethodUrl();
+        TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCallback();
+
+        BidirectionalStream.Builder builder =
+                mCronetEngine
+                        .newBidirectionalStreamBuilder(url, callback, callback.getExecutor())
+                        .setHttpMethod("GET");
+
+        builder.bindToNetwork(defaultNetwork.getNetworkHandle());
+        builder.build().start();
+        callback.blockForDone();
+        assertThat(callback.getResponseInfoWithChecks()).hasHttpStatusCodeThat().isEqualTo(200);
+    }
+
     /**
      * Cronet does not currently provide an API to wait for the active request count to change. We
      * can't just wait for the terminal callback to fire because Cronet updates the count some time
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
index c27e0cce..ba1d61d4fb 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
@@ -5,9 +5,9 @@
 package org.chromium.net;
 
 import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.TruthJUnit.assume;
 
 import static org.junit.Assert.assertThrows;
-import static org.junit.Assume.assumeTrue;
 
 import static org.chromium.net.CronetEngine.Builder.HTTP_CACHE_IN_MEMORY;
 import static org.chromium.net.CronetTestRule.getTestStorage;
@@ -46,6 +46,7 @@
 import org.chromium.net.httpflags.BaseFeature;
 import org.chromium.net.httpflags.FlagValue;
 import org.chromium.net.httpflags.Flags;
+import org.chromium.net.impl.CronetExceptionImpl;
 import org.chromium.net.impl.CronetLibraryLoader;
 import org.chromium.net.impl.CronetManifest;
 import org.chromium.net.impl.CronetManifestInterceptor;
@@ -590,7 +591,7 @@
         ConnectivityManagerDelegate delegate =
                 new ConnectivityManagerDelegate(mTestRule.getTestFramework().getContext());
         Network defaultNetwork = delegate.getDefaultNetwork();
-        assumeTrue(defaultNetwork != null);
+        assume().that(defaultNetwork).isNotNull();
 
         TestUrlRequestCallback callback = new TestUrlRequestCallback();
         // Allows to check the underlying network-bound context state while the request is in
@@ -655,7 +656,7 @@
         ConnectivityManagerDelegate delegate =
                 new ConnectivityManagerDelegate(mTestRule.getTestFramework().getContext());
         Network defaultNetwork = delegate.getDefaultNetwork();
-        assumeTrue(defaultNetwork != null);
+        assume().that(defaultNetwork).isNotNull();
 
         urlRequestBuilder.bindToNetwork(defaultNetwork.getNetworkHandle());
         UrlRequest urlRequest = urlRequestBuilder.build();
@@ -691,21 +692,31 @@
 
     @Test
     @RequiresMinAndroidApi(Build.VERSION_CODES.M)
-    @IgnoreFor(
-            implementations = {CronetImplementation.AOSP_PLATFORM},
-            reason = "crbug.com/1494917")
     public void testBindToInvalidNetworkFails() {
         ExperimentalCronetEngine cronetEngine = mTestRule.getTestFramework().startEngine();
         TestUrlRequestCallback callback = new TestUrlRequestCallback();
+        if (mTestRule.implementationUnderTest() == CronetImplementation.AOSP_PLATFORM) {
+            // HttpEngine#bindToNetwork requires an android.net.Network object. So, in this case, it
+            // will be the wrapper layer that will fail to translate that to a Network, not
+            // something in net's code. Hence, the failure will manifest itself at bind time, not at
+            // request execution time.
+            // Note: this will never happen in prod, as translation failure can only happen if we're
+            // given a fake networkHandle.
+            assertThrows(
+                    IllegalArgumentException.class,
+                    () -> cronetEngine.bindToNetwork(-150 /* invalid network handle */));
+            return;
+        }
+
         cronetEngine.bindToNetwork(-150 /* invalid network handle */);
         ExperimentalUrlRequest.Builder builder =
                 cronetEngine.newUrlRequestBuilder(mUrl, callback, callback.getExecutor());
         builder.build().start();
         callback.blockForDone();
 
-        if (mTestRule.testingJavaImpl()) {
-            assertThat(callback.mError)
-                    .isInstanceOf(org.chromium.net.impl.CronetExceptionImpl.class);
+        assertThat(callback.mError).isNotNull();
+        if (mTestRule.implementationUnderTest() == CronetImplementation.FALLBACK) {
+            assertThat(callback.mError).isInstanceOf(CronetExceptionImpl.class);
             assertThat(callback.mError).hasCauseThat().isInstanceOf(NetworkExceptionImpl.class);
         } else {
             assertThat(callback.mError).isInstanceOf(NetworkExceptionImpl.class);
@@ -718,7 +729,7 @@
         ConnectivityManagerDelegate delegate =
                 new ConnectivityManagerDelegate(mTestRule.getTestFramework().getContext());
         Network defaultNetwork = delegate.getDefaultNetwork();
-        assumeTrue(defaultNetwork != null);
+        assume().that(defaultNetwork).isNotNull();
 
         ExperimentalCronetEngine cronetEngine = mTestRule.getTestFramework().startEngine();
         cronetEngine.bindToNetwork(defaultNetwork.getNetworkHandle());
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java
index 1bcb2fc..9e4ab558 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java
@@ -6,10 +6,10 @@
 
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.common.truth.TruthJUnit.assume;
 
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
 
 import static org.chromium.net.truth.UrlResponseInfoSubject.assertThat;
 
@@ -39,6 +39,7 @@
 import org.chromium.net.TestUrlRequestCallback.FailureType;
 import org.chromium.net.TestUrlRequestCallback.ResponseStep;
 import org.chromium.net.apihelpers.UploadDataProviders;
+import org.chromium.net.impl.CronetExceptionImpl;
 import org.chromium.net.impl.CronetUrlRequest;
 import org.chromium.net.impl.NetworkExceptionImpl;
 import org.chromium.net.impl.UrlResponseInfoImpl;
@@ -181,9 +182,6 @@
 
     @Test
     @SmallTest
-    @IgnoreFor(
-            implementations = {CronetImplementation.AOSP_PLATFORM},
-            reason = "crbug.com/1497531: Figure out what how to handle getProxy checks")
     public void testSimpleGet() throws Exception {
         String url = NativeTestServer.getEchoMethodURL();
         TestUrlRequestCallback callback = startAndWaitForComplete(url);
@@ -284,9 +282,6 @@
      */
     @Test
     @SmallTest
-    @IgnoreFor(
-            implementations = {CronetImplementation.AOSP_PLATFORM},
-            reason = "crbug.com/1497531: Figure out what how to handle getProxy checks")
     public void testRedirectAsync() throws Exception {
         // Start the request and wait to see the redirect.
         TestUrlRequestCallback callback = new TestUrlRequestCallback();
@@ -513,10 +508,8 @@
     @Test
     @SmallTest
     @IgnoreFor(
-            implementations = {CronetImplementation.FALLBACK, CronetImplementation.AOSP_PLATFORM},
-            reason =
-                    "No canonical exception to assert on. "
-                            + "crbug.com/1497531: Figure out what how to handle getProxy checks")
+            implementations = {CronetImplementation.FALLBACK},
+            reason = "No canonical exception to assert on")
     public void testContentLengthMismatchFailsOnce() throws Exception {
         String url = NativeTestServer.getFileURL("/content_length_mismatch.html");
         TestUrlRequestCallback callback = startAndWaitForComplete(url);
@@ -1064,10 +1057,8 @@
     @Test
     @SmallTest
     @IgnoreFor(
-            implementations = {CronetImplementation.FALLBACK, CronetImplementation.AOSP_PLATFORM},
-            reason =
-                    "No canonical exception to assert on. "
-                            + "crbug.com/1497531: Figure out what how to handle getProxy checks")
+            implementations = {CronetImplementation.FALLBACK},
+            reason = "No canonical exception to assert on")
     public void testSimpleGetBufferUpdates() throws Exception {
         TestUrlRequestCallback callback = new TestUrlRequestCallback();
         callback.setAutoAdvance(false);
@@ -2957,44 +2948,56 @@
     }
 
     @Test
-    @SmallTest
     @RequiresMinAndroidApi(Build.VERSION_CODES.M)
-    @IgnoreFor(
-            implementations = {CronetImplementation.AOSP_PLATFORM},
-            reason = "crbug.com/1494845")
-    public void testBindToNetwork() {
+    public void testBindToInvalidNetworkFails() {
         String url = NativeTestServer.getEchoMethodURL();
-        // bind to invalid network handle
-        CronetEngine cronetEngine = mTestRule.getTestFramework().getEngine();
+        ExperimentalCronetEngine cronetEngine = mTestRule.getTestFramework().getEngine();
         TestUrlRequestCallback callback = new TestUrlRequestCallback();
-        UrlRequest.Builder builder =
-                cronetEngine
-                        .newUrlRequestBuilder(url, callback, callback.getExecutor())
-                        .bindToNetwork(-150 /* invalid network handle */);
+        ExperimentalUrlRequest.Builder builder =
+                cronetEngine.newUrlRequestBuilder(url, callback, callback.getExecutor());
+
+        if (mTestRule.implementationUnderTest() == CronetImplementation.AOSP_PLATFORM) {
+            // android.net.http.UrlRequestBuilder#bindToNetwork requires an android.net.Network
+            // object. So, in this case, it
+            // will be the wrapper layer that will fail to translate that to a Network, not
+            // something in net's code. Hence, the failure will manifest itself at bind time, not at
+            // request execution time.
+            // Note: this will never happen in prod, as translation failure can only happen if we're
+            // given a fake networkHandle.
+            assertThrows(
+                    IllegalArgumentException.class,
+                    () -> builder.bindToNetwork(-150 /* invalid network handle */));
+            return;
+        }
+
+        builder.bindToNetwork(-150 /* invalid network handle */);
         builder.build().start();
         callback.blockForDone();
-
-        if (mTestRule.testingJavaImpl()) {
-            assertThat(callback.mError)
-                    .isInstanceOf(org.chromium.net.impl.CronetExceptionImpl.class);
+        assertThat(callback.mError).isNotNull();
+        if (mTestRule.implementationUnderTest() == CronetImplementation.FALLBACK) {
+            assertThat(callback.mError).isInstanceOf(CronetExceptionImpl.class);
             assertThat(callback.mError).hasCauseThat().isInstanceOf(NetworkExceptionImpl.class);
         } else {
             assertThat(callback.mError).isInstanceOf(NetworkExceptionImpl.class);
         }
+    }
 
-        // bind to the default network
+    @Test
+    @RequiresMinAndroidApi(Build.VERSION_CODES.M)
+    public void testBindToDefaultNetworkSucceeds() {
+        String url = NativeTestServer.getEchoMethodURL();
         ConnectivityManagerDelegate delegate =
                 new ConnectivityManagerDelegate(mTestRule.getTestFramework().getContext());
         Network defaultNetwork = delegate.getDefaultNetwork();
-        assumeTrue(defaultNetwork != null);
-        callback = new TestUrlRequestCallback();
-        builder =
-                cronetEngine
-                        .newUrlRequestBuilder(url, callback, callback.getExecutor())
-                        .bindToNetwork(defaultNetwork.getNetworkHandle());
+        assume().that(defaultNetwork).isNotNull();
+
+        ExperimentalCronetEngine cronetEngine = mTestRule.getTestFramework().getEngine();
+        TestUrlRequestCallback callback = new TestUrlRequestCallback();
+        ExperimentalUrlRequest.Builder builder =
+                cronetEngine.newUrlRequestBuilder(url, callback, callback.getExecutor());
+        builder.bindToNetwork(defaultNetwork.getNetworkHandle());
         builder.build().start();
         callback.blockForDone();
-
         assertThat(callback.getResponseInfoWithChecks()).hasHttpStatusCodeThat().isEqualTo(200);
     }
 
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetHttpURLStreamHandlerTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetHttpURLStreamHandlerTest.java
index 53315e5b..1fd392d 100644
--- a/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetHttpURLStreamHandlerTest.java
+++ b/components/cronet/android/test/javatests/src/org/chromium/net/urlconnection/CronetHttpURLStreamHandlerTest.java
@@ -75,11 +75,6 @@
 
     @Test
     @SmallTest
-    @IgnoreFor(
-            implementations = {CronetImplementation.AOSP_PLATFORM},
-            reason =
-                    "crbug.com/1494845: CronetExceptionTranslationUtils fails to translate "
-                            + "java.lang.UnsupportedOperationException")
     public void testOpenConnectionProtocolNotSupported() throws Exception {
         URL url = new URL("ftp://example.com");
         CronetHttpURLStreamHandler streamHandler =
diff --git a/components/cronet/tools/cr_cronet.py b/components/cronet/tools/cr_cronet.py
index c16409f..92584d5 100755
--- a/components/cronet/tools/cr_cronet.py
+++ b/components/cronet/tools/cr_cronet.py
@@ -63,7 +63,7 @@
   remote_netlog_dir = '/data/data/org.chromium.net.tests/app_cronet_test/NetLog'
   run(['adb', 'shell', 'rm', '-rf', remote_netlog_dir])
   run([out_dir + '/bin/run_cronet_test_instrumentation_apk'] + extra_options)
-  local_netlog_dir = 'netlogs_for-' + datetime.now().strftime(
+  local_netlog_dir = out_dir + '/netlogs_for-' + datetime.now().strftime(
       "%y_%m_%d-%H_%M_%S")
   return run(['adb', 'pull', remote_netlog_dir, local_netlog_dir])
 
diff --git a/components/device_signals/test/win/scoped_executable_files.h b/components/device_signals/test/win/scoped_executable_files.h
index a26d885..d99f115 100644
--- a/components/device_signals/test/win/scoped_executable_files.h
+++ b/components/device_signals/test/win/scoped_executable_files.h
@@ -6,7 +6,7 @@
 #define COMPONENTS_DEVICE_SIGNALS_TEST_WIN_SCOPED_EXECUTABLE_FILES_H_
 
 #include "base/files/scoped_temp_dir.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/threading/thread_restrictions.h"
 
 namespace base {
diff --git a/components/digital_goods/mojom/digital_goods.mojom b/components/digital_goods/mojom/digital_goods.mojom
index 8800c57..8d49deeb 100644
--- a/components/digital_goods/mojom/digital_goods.mojom
+++ b/components/digital_goods/mojom/digital_goods.mojom
@@ -24,7 +24,7 @@
 
   // Unknown error calling a Digital Goods action (a more specific error code
   // below is preferred).
-  kError,
+  [Default] kError,
 
   // Item purchased is already owned.
   kItemAlreadyOwned,
@@ -44,7 +44,7 @@
 
 [Extensible, Stable]
 enum ItemType {
-  kUnknown,
+  [Default] kUnknown,
   kProduct,
   kSubscription,
 };
@@ -73,7 +73,7 @@
 [Extensible, Stable]
 enum CreateDigitalGoodsResponseCode {
   kOk,
-  kError,
+  [Default] kError,
   kUnsupportedPaymentMethod,
   kUnsupportedContext,
 };
diff --git a/components/dom_distiller/core/url_utils.h b/components/dom_distiller/core/url_utils.h
index 4b37325..896e5f6 100644
--- a/components/dom_distiller/core/url_utils.h
+++ b/components/dom_distiller/core/url_utils.h
@@ -7,7 +7,7 @@
 
 #include <string>
 
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 
 class GURL;
 
diff --git a/components/drive/drive_notification_manager.h b/components/drive/drive_notification_manager.h
index 0e03a3a..ef56a2f 100644
--- a/components/drive/drive_notification_manager.h
+++ b/components/drive/drive_notification_manager.h
@@ -15,7 +15,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "base/sequence_checker.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/time/default_tick_clock.h"
 #include "base/timer/timer.h"
 #include "components/drive/drive_notification_observer.h"
diff --git a/components/enterprise/browser/controller/browser_dm_token_storage.h b/components/enterprise/browser/controller/browser_dm_token_storage.h
index 76f4235..dd90a52 100644
--- a/components/enterprise/browser/controller/browser_dm_token_storage.h
+++ b/components/enterprise/browser/controller/browser_dm_token_storage.h
@@ -14,7 +14,7 @@
 #include "base/no_destructor.h"
 #include "base/run_loop.h"
 #include "base/sequence_checker.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/system/sys_info.h"
 #include "base/task/single_thread_task_runner.h"
 #include "components/policy/core/common/cloud/dm_token.h"
diff --git a/components/exo/wm_helper.cc b/components/exo/wm_helper.cc
index dfd3a81..5f6afab1 100644
--- a/components/exo/wm_helper.cc
+++ b/components/exo/wm_helper.cc
@@ -82,13 +82,68 @@
   // Exo windows have their window tree up to the root surface disconnected
   // (see crbug.com/1405015). We want to keep them in debug output though, so
   // special case them here.
-  std::vector<aura::Window*> GetAdjustedChildren(
+  std::vector<aura::Window*> GetAdjustedWindowChildren(
       aura::Window* window) const override {
-    Surface* surface = Surface::AsSurface(window);
-    if (!surface || window->children().size()) {
-      return window->children();
+    if (ShouldUseAdjustedChildren(window)) {
+      return Surface::AsSurface(window)->GetChildWindows();
     }
-    return surface->GetChildWindows();
+    return window->children();
+  }
+
+  std::vector<ui::Layer*> GetAdjustedLayerChildren(
+      const ui::Layer* layer) const override {
+    // For non-exo windows, just return the regular children. Note that we still
+    // need to check leaf layers with no children.
+    if (!layer->children().empty()) {
+      return layer->children();
+    }
+
+    // Attempt to map this layer to the window that owns it.
+    auto* window = MaybeGetWindowForLayer(layer);
+    // If we found a window and it should have adjusted children, grab the
+    // layers from its child windows.
+    if (window && ShouldUseAdjustedChildren(window)) {
+      std::vector<ui::Layer*> children;
+      for (aura::Window* child : GetAdjustedWindowChildren(window)) {
+        children.push_back(child->layer());
+      }
+      return children;
+    }
+    return layer->children();
+  }
+
+ private:
+  // True if we should use adjusted children (e.g. the exo root surface window).
+  bool ShouldUseAdjustedChildren(aura::Window* window) const {
+    return Surface::AsSurface(window) && !window->children().size();
+  }
+
+  // We are doing a traversal of the entire window tree for each layer, which
+  // may be slow. This is only called on debug methods to print the hierarchy,
+  // so it should be fine. It is otherwise difficult to map from a layer to a
+  // window.
+  aura::Window* MaybeGetWindowForLayer(const ui::Layer* layer) const {
+    for (auto* root_window : ash::Shell::Get()->GetAllRootWindows()) {
+      auto* window = MaybeGetWindowForLayerImpl(root_window, layer);
+      if (window != nullptr) {
+        return window;
+      }
+    }
+    return nullptr;
+  }
+
+  aura::Window* MaybeGetWindowForLayerImpl(aura::Window* parent,
+                                           const ui::Layer* layer) const {
+    if (parent->layer() == layer) {
+      return parent;
+    }
+    for (auto* child : GetAdjustedWindowChildren(parent)) {
+      auto* window = MaybeGetWindowForLayerImpl(child, layer);
+      if (window != nullptr) {
+        return window;
+      }
+    }
+    return nullptr;
   }
 };
 
diff --git a/components/feed/core/v2/api_test/feed_api_test.h b/components/feed/core/v2/api_test/feed_api_test.h
index 6adc35d..cf16c24 100644
--- a/components/feed/core/v2/api_test/feed_api_test.h
+++ b/components/feed/core/v2/api_test/feed_api_test.h
@@ -11,7 +11,7 @@
 #include <vector>
 
 #include "base/functional/callback_forward.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "base/time/time.h"
diff --git a/components/feed/core/v2/enums.h b/components/feed/core/v2/enums.h
index 6b1257d..dc65567 100644
--- a/components/feed/core/v2/enums.h
+++ b/components/feed/core/v2/enums.h
@@ -6,7 +6,7 @@
 #define COMPONENTS_FEED_CORE_V2_ENUMS_H_
 
 #include <iosfwd>
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 
 namespace feed {
 
diff --git a/components/feed/core/v2/feedstore_util.h b/components/feed/core/v2/feedstore_util.h
index 87ae691..3164486f 100644
--- a/components/feed/core/v2/feedstore_util.h
+++ b/components/feed/core/v2/feedstore_util.h
@@ -7,7 +7,7 @@
 
 #include <string>
 #include "base/containers/flat_set.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "components/feed/core/proto/v2/store.pb.h"
 #include "components/feed/core/v2/public/stream_type.h"
diff --git a/components/feed/core/v2/public/feed_api.h b/components/feed/core/v2/public/feed_api.h
index 6031cc0..bd4d529 100644
--- a/components/feed/core/v2/public/feed_api.h
+++ b/components/feed/core/v2/public/feed_api.h
@@ -10,7 +10,7 @@
 
 #include "base/functional/callback_forward.h"
 #include "base/observer_list_types.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "components/feed/core/v2/public/common_enums.h"
 #include "components/feed/core/v2/public/refresh_task_scheduler.h"
diff --git a/components/feed/core/v2/web_feed_subscriptions/web_feed_index.h b/components/feed/core/v2/web_feed_subscriptions/web_feed_index.h
index f690eb22..ca719fa 100644
--- a/components/feed/core/v2/web_feed_subscriptions/web_feed_index.h
+++ b/components/feed/core/v2/web_feed_subscriptions/web_feed_index.h
@@ -7,7 +7,7 @@
 
 #include <iosfwd>
 
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "components/feed/core/proto/v2/store.pb.h"
 #include "components/feed/core/v2/enums.h"
diff --git a/components/fuchsia_component_support/annotations_manager.h b/components/fuchsia_component_support/annotations_manager.h
index 45a9ba05..0c2afbb 100644
--- a/components/fuchsia_component_support/annotations_manager.h
+++ b/components/fuchsia_component_support/annotations_manager.h
@@ -12,7 +12,7 @@
 #include <vector>
 
 #include "base/containers/flat_map.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 
 namespace fuchsia_component_support {
 
diff --git a/components/fuchsia_component_support/dynamic_component_host.h b/components/fuchsia_component_support/dynamic_component_host.h
index b3a7fe4..d22946a 100644
--- a/components/fuchsia_component_support/dynamic_component_host.h
+++ b/components/fuchsia_component_support/dynamic_component_host.h
@@ -12,7 +12,7 @@
 #include <string>
 
 #include "base/functional/callback.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 
 namespace sys {
 class ServiceDirectory;
diff --git a/components/fuchsia_component_support/feedback_registration.h b/components/fuchsia_component_support/feedback_registration.h
index 4cf8e3cb..365a4957 100644
--- a/components/fuchsia_component_support/feedback_registration.h
+++ b/components/fuchsia_component_support/feedback_registration.h
@@ -5,7 +5,7 @@
 #ifndef COMPONENTS_FUCHSIA_COMPONENT_SUPPORT_FEEDBACK_REGISTRATION_H_
 #define COMPONENTS_FUCHSIA_COMPONENT_SUPPORT_FEEDBACK_REGISTRATION_H_
 
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 
 namespace fuchsia_component_support {
 
diff --git a/components/global_media_controls/public/test/mock_media_item_ui_device_selector.h b/components/global_media_controls/public/test/mock_media_item_ui_device_selector.h
index 04b462c..518b2b48 100644
--- a/components/global_media_controls/public/test/mock_media_item_ui_device_selector.h
+++ b/components/global_media_controls/public/test/mock_media_item_ui_device_selector.h
@@ -23,7 +23,8 @@
   MOCK_METHOD(void, SetMediaItemUIView, (MediaItemUIView*));
   MOCK_METHOD(void, OnColorsChanged, (SkColor, SkColor));
   MOCK_METHOD(void, UpdateCurrentAudioDevice, (const std::string&));
-  MOCK_METHOD(void, ShowOrHideDeviceList, ());
+  MOCK_METHOD(void, ShowDevices, ());
+  MOCK_METHOD(void, HideDevices, ());
   MOCK_METHOD(bool, IsDeviceSelectorExpanded, ());
 
   MOCK_METHOD(void, Die, ());
diff --git a/components/global_media_controls/public/views/media_item_ui_device_selector.h b/components/global_media_controls/public/views/media_item_ui_device_selector.h
index 0ac75cb..e3b85b4 100644
--- a/components/global_media_controls/public/views/media_item_ui_device_selector.h
+++ b/components/global_media_controls/public/views/media_item_ui_device_selector.h
@@ -27,9 +27,11 @@
   virtual void UpdateCurrentAudioDevice(
       const std::string& current_device_id) = 0;
 
-  // Called to show the device list if it is hidden before, or hide the device
-  // list if it is shown before.
-  virtual void ShowOrHideDeviceList() = 0;
+  // Called to show the device list since it is hidden before.
+  virtual void ShowDevices() = 0;
+
+  // Called to hide the device list since it is shown before.
+  virtual void HideDevices() = 0;
 
   // Returns whether the device list has been expanded.
   virtual bool IsDeviceSelectorExpanded() = 0;
diff --git a/components/global_media_controls/public/views/media_item_ui_view.cc b/components/global_media_controls/public/views/media_item_ui_view.cc
index 6f68f526..604b8090 100644
--- a/components/global_media_controls/public/views/media_item_ui_view.cc
+++ b/components/global_media_controls/public/views/media_item_ui_view.cc
@@ -52,6 +52,7 @@
 constexpr int kCrOSDismissButtonIconSize = 12;
 constexpr gfx::Size kModernDismissButtonSize = gfx::Size(14, 14);
 constexpr int kModernDismissButtonIconSize = 10;
+constexpr int kCrOSDeviceSelectorSeparatorHeight = 22;
 constexpr gfx::Insets kSwipeableContainerInsets =
     gfx::Insets::TLBR(4, 16, 8, 16);
 
@@ -101,26 +102,26 @@
   // The updated UI requires media color theme to be set while the toolbar
   // media button does not provide it, so we need to verify the source display
   // page is from the quick settings.
-  bool use_cros_updated_ui =
+  use_cros_updated_ui_ =
       base::FeatureList::IsEnabled(media::kGlobalMediaControlsCrOSUpdatedUI) &&
       chromeos::features::IsJellyrollEnabled() &&
       media_display_page.has_value();
 #else
-  bool use_cros_updated_ui = false;
+  use_cros_updated_ui_ = false;
 #endif
 
   auto swipeable_container = std::make_unique<views::View>();
   swipeable_container->SetLayoutManager(std::make_unique<views::FillLayout>());
   swipeable_container->SetPaintToLayer();
   swipeable_container->layer()->SetFillsBoundsOpaquely(false);
-  if (use_cros_updated_ui) {
+  if (use_cros_updated_ui_) {
     swipeable_container->SetBorder(
         views::CreateEmptyBorder(kSwipeableContainerInsets));
   }
   swipeable_container_ = AddChildView(std::move(swipeable_container));
 
   std::unique_ptr<media_message_center::MediaNotificationView> view;
-  if (use_cros_updated_ui) {
+  if (use_cros_updated_ui_) {
     CHECK(media_color_theme.has_value());
     if (footer_view) {
       footer_view_ = footer_view.get();
@@ -467,7 +468,10 @@
 
 void MediaItemUIView::OnSizeChanged() {
   gfx::Size new_size;
-  if (base::FeatureList::IsEnabled(media::kGlobalMediaControlsModernUI)) {
+  if (use_cros_updated_ui_) {
+    new_size = kCrOSMediaItemUpdatedUISize;
+  } else if (base::FeatureList::IsEnabled(
+                 media::kGlobalMediaControlsModernUI)) {
     new_size = kModernUISize;
   } else {
     new_size = is_expanded_ ? kExpandedSize : kNormalSize;
@@ -479,12 +483,18 @@
   if (device_selector_view_) {
     auto device_selector_view_size = device_selector_view_->GetPreferredSize();
     CHECK(device_selector_view_size.width() == kWidth);
-    new_size.set_height(new_size.height() + device_selector_view_size.height());
+    if (device_selector_view_size.height() > 0) {
+      new_size.set_height(new_size.height() +
+                          device_selector_view_size.height());
+      if (use_cros_updated_ui_) {
+        new_size.set_height(new_size.height() +
+                            kCrOSDeviceSelectorSeparatorHeight);
+      }
+    }
     view_->UpdateDeviceSelectorVisibility(device_selector_view_->GetVisible());
   }
 
   SetPreferredSize(new_size);
-  PreferredSizeChanged();
 
   for (auto& observer : observers_)
     observer.OnMediaItemUISizeChanged();
diff --git a/components/global_media_controls/public/views/media_item_ui_view.h b/components/global_media_controls/public/views/media_item_ui_view.h
index 93c589e1..c515b87 100644
--- a/components/global_media_controls/public/views/media_item_ui_view.h
+++ b/components/global_media_controls/public/views/media_item_ui_view.h
@@ -98,6 +98,7 @@
                        SkColor background) override;
   void OnHeaderClicked() override;
   void OnShowCastingDevicesRequested() override;
+  void OnDeviceSelectorViewSizeChanged() override;
 
   // views::SlideOutControllerDelegate:
   ui::Layer* GetSlideOutLayer() override;
@@ -114,9 +115,6 @@
   // Called when the devices in the device selector view have changed.
   void OnDeviceSelectorViewDevicesChanged(bool has_devices);
 
-  // Called when the size of the device selector view has changed.
-  void OnDeviceSelectorViewSizeChanged();
-
   const std::u16string& GetTitle() const;
 
   // Set the scroll view that is currently holding this item.
@@ -201,6 +199,9 @@
 
   // Sets to true when the notification theme is provided on Chrome OS.
   const bool has_notification_theme_;
+
+  // Sets to true if the updated UI is enabled on Chrome OS.
+  bool use_cros_updated_ui_ = false;
 };
 
 }  // namespace global_media_controls
diff --git a/components/global_media_controls/public/views/media_notification_view_ash_impl.cc b/components/global_media_controls/public/views/media_notification_view_ash_impl.cc
index 2b546fd..e8b1a76 100644
--- a/components/global_media_controls/public/views/media_notification_view_ash_impl.cc
+++ b/components/global_media_controls/public/views/media_notification_view_ash_impl.cc
@@ -570,9 +570,13 @@
     }
     case MediaDisplayPage::kQuickSettingsMediaDetailedView:
     case MediaDisplayPage::kSystemShelfMediaDetailedView: {
-      // Clicking the button on the media detailed view will open the device
-      // selector view to show the device list.
-      device_selector_view_->ShowOrHideDeviceList();
+      // Clicking the button on the media detailed view will toggle the device
+      // list in the device selector view.
+      if (device_selector_view_->IsDeviceSelectorExpanded()) {
+        device_selector_view_->HideDevices();
+      } else {
+        device_selector_view_->ShowDevices();
+      }
       UpdateCastingState();
       break;
     }
@@ -586,31 +590,34 @@
   CHECK(device_selector_view_);
   CHECK(device_selector_view_separator_);
 
-  if (!start_casting_button_->GetVisible()) {
+  if (start_casting_button_->GetVisible()) {
+    device_selector_view_->SetVisible(true);
+    bool is_expanded = device_selector_view_->IsDeviceSelectorExpanded();
+    if (is_expanded) {
+      // Use the ink drop color as the button background if user clicks the
+      // button to show devices.
+      views::InkDrop::Get(start_casting_button_)
+          ->GetInkDrop()
+          ->SnapToActivated();
+
+      // Indicate the user can hide the device list.
+      start_casting_button_->UpdateText(
+          IDS_MEDIA_MESSAGE_CENTER_MEDIA_NOTIFICATION_ACTION_HIDE_DEVICE_LIST);
+    } else {
+      // Hide the ink drop color if user clicks the button to hide devices.
+      views::InkDrop::Get(start_casting_button_)->GetInkDrop()->SnapToHidden();
+
+      // Indicate the user can show the device list.
+      start_casting_button_->UpdateText(
+          IDS_MEDIA_MESSAGE_CENTER_MEDIA_NOTIFICATION_ACTION_SHOW_DEVICE_LIST);
+    }
+    device_selector_view_separator_->SetVisible(is_expanded);
+  } else {
     device_selector_view_->SetVisible(false);
     device_selector_view_separator_->SetVisible(false);
-    return;
   }
 
-  device_selector_view_->SetVisible(true);
-  bool is_expanded = device_selector_view_->IsDeviceSelectorExpanded();
-  if (is_expanded) {
-    // Use the ink drop color as the button background if user clicks the button
-    // to show devices.
-    views::InkDrop::Get(start_casting_button_)->GetInkDrop()->SnapToActivated();
-
-    // Indicate the user can hide the device list.
-    start_casting_button_->UpdateText(
-        IDS_MEDIA_MESSAGE_CENTER_MEDIA_NOTIFICATION_ACTION_HIDE_DEVICE_LIST);
-  } else {
-    // Hide the ink drop color if user clicks the button to hide devices.
-    views::InkDrop::Get(start_casting_button_)->GetInkDrop()->SnapToHidden();
-
-    // Indicate the user can show the device list.
-    start_casting_button_->UpdateText(
-        IDS_MEDIA_MESSAGE_CENTER_MEDIA_NOTIFICATION_ACTION_SHOW_DEVICE_LIST);
-  }
-  device_selector_view_separator_->SetVisible(is_expanded);
+  container_->OnDeviceSelectorViewSizeChanged();
 }
 
 // Helper functions for testing:
diff --git a/components/global_media_controls/public/views/media_notification_view_ash_impl_unittest.cc b/components/global_media_controls/public/views/media_notification_view_ash_impl_unittest.cc
index 6c0259d..48eb0cdb 100644
--- a/components/global_media_controls/public/views/media_notification_view_ash_impl_unittest.cc
+++ b/components/global_media_controls/public/views/media_notification_view_ash_impl_unittest.cc
@@ -24,6 +24,7 @@
 using ::media_session::mojom::MediaSessionAction;
 using ::testing::_;
 using ::testing::NiceMock;
+using ::testing::Return;
 
 namespace {
 
@@ -207,20 +208,33 @@
   EXPECT_NE(view()->GetDeviceSelectorSeparatorForTesting(), nullptr);
   EXPECT_FALSE(view()->GetDeviceSelectorSeparatorForTesting()->GetVisible());
 
+  // Add devices to the list to show the start casting button.
   EXPECT_CALL(*device_selector(), IsDeviceSelectorExpanded())
-      .WillOnce(testing::Return(false));
+      .WillOnce(Return(false));
   view()->UpdateDeviceSelectorAvailability(/*has_devices=*/true);
   EXPECT_TRUE(view()->GetStartCastingButtonForTesting()->GetVisible());
   EXPECT_TRUE(view()->GetDeviceSelectorForTesting()->GetVisible());
   EXPECT_FALSE(view()->GetDeviceSelectorSeparatorForTesting()->GetVisible());
 
-  EXPECT_CALL(*device_selector(), ShowOrHideDeviceList());
+  // Click the start casting button to show devices.
+  EXPECT_CALL(*device_selector(), ShowDevices());
   EXPECT_CALL(*device_selector(), IsDeviceSelectorExpanded())
-      .WillOnce(testing::Return(true));
+      .WillOnce(Return(false))
+      .WillOnce(Return(true));
   views::test::ButtonTestApi(view()->GetStartCastingButtonForTesting())
       .NotifyClick(ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(),
                                   gfx::Point(), ui::EventTimeForNow(), 0, 0));
   EXPECT_TRUE(view()->GetDeviceSelectorSeparatorForTesting()->GetVisible());
+
+  // Click the start casting button to hide devices.
+  EXPECT_CALL(*device_selector(), HideDevices());
+  EXPECT_CALL(*device_selector(), IsDeviceSelectorExpanded())
+      .WillOnce(Return(true))
+      .WillOnce(Return(false));
+  views::test::ButtonTestApi(view()->GetStartCastingButtonForTesting())
+      .NotifyClick(ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(),
+                                  gfx::Point(), ui::EventTimeForNow(), 0, 0));
+  EXPECT_FALSE(view()->GetDeviceSelectorSeparatorForTesting()->GetVisible());
 }
 
 TEST_F(MediaNotificationViewAshImplTest, FooterViewCheck) {
diff --git a/components/gwp_asan/client/lightweight_detector/poison_metadata_recorder.cc b/components/gwp_asan/client/lightweight_detector/poison_metadata_recorder.cc
index 59fed77c..cdce31f 100644
--- a/components/gwp_asan/client/lightweight_detector/poison_metadata_recorder.cc
+++ b/components/gwp_asan/client/lightweight_detector/poison_metadata_recorder.cc
@@ -112,6 +112,6 @@
 }
 
 template class EXPORT_TEMPLATE_DEFINE(GWP_ASAN_EXPORT)
-    SharedState<PoisonMetadataRecorder>;
+    SharedStateHolder<PoisonMetadataRecorder>;
 
 }  // namespace gwp_asan::internal
diff --git a/components/gwp_asan/client/lightweight_detector/poison_metadata_recorder.h b/components/gwp_asan/client/lightweight_detector/poison_metadata_recorder.h
index 7da51783..172ed01c 100644
--- a/components/gwp_asan/client/lightweight_detector/poison_metadata_recorder.h
+++ b/components/gwp_asan/client/lightweight_detector/poison_metadata_recorder.h
@@ -16,10 +16,6 @@
 
 namespace gwp_asan::internal {
 
-class PoisonMetadataRecorder;
-extern template class EXPORT_TEMPLATE_DECLARE(GWP_ASAN_EXPORT)
-    SharedState<PoisonMetadataRecorder>;
-
 // Responsible for both poisoning memory allocations and tracking metadata
 // associated with these poisoned allocations.
 class GWP_ASAN_EXPORT PoisonMetadataRecorder
@@ -63,6 +59,9 @@
   FRIEND_TEST_ALL_PREFIXES(LightweightDetectorAnalyzerTest, InternalError);
 };
 
+extern template class EXPORT_TEMPLATE_DECLARE(GWP_ASAN_EXPORT)
+    SharedStateHolder<PoisonMetadataRecorder>;
+
 }  // namespace gwp_asan::internal
 
 #endif  // COMPONENTS_GWP_ASAN_CLIENT_LIGHTWEIGHT_DETECTOR_POISON_METADATA_RECORDER_H_
diff --git a/components/gwp_asan/client/lightweight_detector/shared_state.h b/components/gwp_asan/client/lightweight_detector/shared_state.h
index aeca6b7..0c98a4e 100644
--- a/components/gwp_asan/client/lightweight_detector/shared_state.h
+++ b/components/gwp_asan/client/lightweight_detector/shared_state.h
@@ -5,6 +5,7 @@
 #ifndef COMPONENTS_GWP_ASAN_CLIENT_LIGHTWEIGHT_DETECTOR_SHARED_STATE_H_
 #define COMPONENTS_GWP_ASAN_CLIENT_LIGHTWEIGHT_DETECTOR_SHARED_STATE_H_
 
+#include <stdint.h>
 #include <utility>
 
 #include "base/check.h"
@@ -12,6 +13,24 @@
 
 namespace gwp_asan::internal {
 
+template <typename T>
+class SharedState;
+
+template <typename T>
+class SharedStateHolder {
+ private:
+  static bool initialized_;
+  static uint8_t buffer_[];
+
+  friend class SharedState<T>;
+};
+
+template <typename T>
+bool SharedStateHolder<T>::initialized_ = false;
+
+template <typename T>
+alignas(T) uint8_t SharedStateHolder<T>::buffer_[sizeof(T)];
+
 // Special purpose shared state type. Uses a static buffer to reduce the number
 // of pointer dereferences, requires explicit initialization, and doesn't
 // provide thread safety.
@@ -20,33 +39,27 @@
  public:
   template <typename... Args>
   static void Init(Args&&... args) {
-    instance_initialized_ = true;
+    DCHECK(!Holder::initialized_);
+    Holder::initialized_ = true;
     new (Get()) T(std::forward<Args>(args)...);
   }
 
   ALWAYS_INLINE static T* Get() {
-    DCHECK(instance_initialized_);
-    return reinterpret_cast<T*>(instance_buffer_);
+    DCHECK(Holder::initialized_);
+    return reinterpret_cast<T*>(Holder::buffer_);
   }
 
   static void ResetForTesting() {
-    if (instance_initialized_) {
+    if (Holder::initialized_) {
       Get()->~T();
-      instance_initialized_ = false;
+      Holder::initialized_ = false;
     }
   }
 
  private:
-  static bool instance_initialized_;
-  static uint8_t instance_buffer_[];
+  using Holder = SharedStateHolder<T>;
 };
 
-template <typename T>
-bool SharedState<T>::instance_initialized_ = false;
-
-template <typename T>
-alignas(T) uint8_t SharedState<T>::instance_buffer_[sizeof(T)];
-
 }  // namespace gwp_asan::internal
 
 #endif  // COMPONENTS_GWP_ASAN_CLIENT_LIGHTWEIGHT_DETECTOR_SHARED_STATE_H_
diff --git a/components/history_clusters/core/config.cc b/components/history_clusters/core/config.cc
index a93bab6f..3860038 100644
--- a/components/history_clusters/core/config.cc
+++ b/components/history_clusters/core/config.cc
@@ -9,7 +9,7 @@
 #include "base/feature_list.h"
 #include "base/metrics/field_trial_params.h"
 #include "base/no_destructor.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/strings/string_split.h"
 #include "build/build_config.h"
 #include "components/history_clusters/core/features.h"
diff --git a/components/history_clusters/core/features.cc b/components/history_clusters/core/features.cc
index 7ac4b8e1..613707c 100644
--- a/components/history_clusters/core/features.cc
+++ b/components/history_clusters/core/features.cc
@@ -7,7 +7,7 @@
 #include "base/containers/contains.h"
 #include "base/feature_list.h"
 #include "base/metrics/field_trial_params.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/strings/string_split.h"
 #include "build/build_config.h"
 #include "ui/base/l10n/l10n_util.h"
diff --git a/components/media_message_center/media_notification_container.h b/components/media_message_center/media_notification_container.h
index f1985df..8fc18ef 100644
--- a/components/media_message_center/media_notification_container.h
+++ b/components/media_message_center/media_notification_container.h
@@ -52,6 +52,10 @@
   // settings media detailed view.
   virtual void OnShowCastingDevicesRequested() {}
 
+  // Called when the device selector view size has changed to request UI updates
+  // for view parents.
+  virtual void OnDeviceSelectorViewSizeChanged() {}
+
   // Called when a media action button in MediaNotificationView is pressed and
   // MediaNotificationContainer needs to handle the button event.
   virtual void OnMediaSessionActionButtonPressed(
diff --git a/components/media_router/browser/log_util.h b/components/media_router/browser/log_util.h
index afb890a..225e5f2 100644
--- a/components/media_router/browser/log_util.h
+++ b/components/media_router/browser/log_util.h
@@ -5,7 +5,7 @@
 #ifndef COMPONENTS_MEDIA_ROUTER_BROWSER_LOG_UTIL_H_
 #define COMPONENTS_MEDIA_ROUTER_BROWSER_LOG_UTIL_H_
 
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 
 namespace media_router::log_util {
 
diff --git a/components/media_router/browser/logger_impl.h b/components/media_router/browser/logger_impl.h
index 1c84929..6d5b6a1 100644
--- a/components/media_router/browser/logger_impl.h
+++ b/components/media_router/browser/logger_impl.h
@@ -7,7 +7,7 @@
 
 #include "base/containers/circular_deque.h"
 #include "base/gtest_prod_util.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "base/values.h"
 #include "components/media_router/common/mojom/logger.mojom.h"
diff --git a/components/media_router/common/media_route_provider_helper.h b/components/media_router/common/media_route_provider_helper.h
index f130bb2d..3de4da49 100644
--- a/components/media_router/common/media_route_provider_helper.h
+++ b/components/media_router/common/media_route_provider_helper.h
@@ -5,7 +5,7 @@
 #ifndef COMPONENTS_MEDIA_ROUTER_COMMON_MEDIA_ROUTE_PROVIDER_HELPER_H_
 #define COMPONENTS_MEDIA_ROUTER_COMMON_MEDIA_ROUTE_PROVIDER_HELPER_H_
 
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "components/media_router/common/mojom/media_route_provider_id.mojom-forward.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
diff --git a/components/metrics/generate_expired_histograms_array.gni b/components/metrics/generate_expired_histograms_array.gni
index 8cc8298..3dc5a9e 100644
--- a/components/metrics/generate_expired_histograms_array.gni
+++ b/components/metrics/generate_expired_histograms_array.gni
@@ -97,6 +97,7 @@
       "//tools/metrics/histograms/metadata/fingerprint/histograms.xml",
       "//tools/metrics/histograms/metadata/game_mode/histograms.xml",
       "//tools/metrics/histograms/metadata/gcm/histograms.xml",
+      "//tools/metrics/histograms/metadata/geolocation/enums.xml",
       "//tools/metrics/histograms/metadata/geolocation/histograms.xml",
       "//tools/metrics/histograms/metadata/google/histograms.xml",
       "//tools/metrics/histograms/metadata/gpu/histograms.xml",
@@ -125,6 +126,7 @@
       "//tools/metrics/histograms/metadata/navigation/enums.xml",
       "//tools/metrics/histograms/metadata/navigation/histograms.xml",
       "//tools/metrics/histograms/metadata/nearby/histograms.xml",
+      "//tools/metrics/histograms/metadata/net/enums.xml",
       "//tools/metrics/histograms/metadata/net/histograms.xml",
       "//tools/metrics/histograms/metadata/network/histograms.xml",
       "//tools/metrics/histograms/metadata/new_tab_page/histograms.xml",
diff --git a/components/metrics/metrics_log.h b/components/metrics/metrics_log.h
index 5e820d2e..c12904b 100644
--- a/components/metrics/metrics_log.h
+++ b/components/metrics/metrics_log.h
@@ -16,7 +16,7 @@
 #include "base/functional/callback_forward.h"
 #include "base/memory/raw_ptr.h"
 #include "base/metrics/histogram_base.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "build/chromeos_buildflags.h"
 #include "components/metrics/metrics_reporting_default_state.h"
diff --git a/components/metrics/persistent_histograms.h b/components/metrics/persistent_histograms.h
index fac682f..a30dc053 100644
--- a/components/metrics/persistent_histograms.h
+++ b/components/metrics/persistent_histograms.h
@@ -10,7 +10,7 @@
 #include "base/feature_list.h"
 #include "base/files/file_path.h"
 #include "base/metrics/field_trial_params.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 
 // Feature definition for enabling histogram persistence. Note that this feature
 // (along with its param `kPersistentHistogramsStorage`, declared below) is not
diff --git a/components/ml/webnn/graph_validation_utils.cc b/components/ml/webnn/graph_validation_utils.cc
index e73cee9b..9cb0552 100644
--- a/components/ml/webnn/graph_validation_utils.cc
+++ b/components/ml/webnn/graph_validation_utils.cc
@@ -14,6 +14,7 @@
 #include "base/numerics/checked_math.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/ranges/algorithm.h"
+#include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 
 namespace webnn {
@@ -159,6 +160,34 @@
   return !(*this == other);
 }
 
+std::string DataTypeToString(Operand::DataType data_type) {
+  switch (data_type) {
+    case Operand::DataType::kFloat32:
+      return "float32";
+    case Operand::DataType::kFloat16:
+      return "float16";
+    case Operand::DataType::kInt32:
+      return "int32";
+    case Operand::DataType::kUint32:
+      return "uint32";
+    case Operand::DataType::kInt8:
+      return "int8";
+    case Operand::DataType::kUint8:
+      return "uint8";
+  }
+  NOTREACHED_NORETURN();
+}
+
+std::string DataTypeConstraintToString(
+    const DataTypeConstraintSet& constraint_set) {
+  std::vector<std::string> data_types;
+  data_types.reserve(constraint_set.Size());
+  for (auto data_type : constraint_set) {
+    data_types.push_back(DataTypeToString(data_type));
+  }
+  return base::JoinString(data_types, /* saperator */ ",");
+}
+
 base::expected<Operand, std::string> ValidateSoftmaxAndInferOutput(
     Operand input) {
   // According to WebNN spec:
@@ -1075,17 +1104,7 @@
 }
 
 bool IsFloatingPointType(Operand::DataType data_type) {
-  switch (data_type) {
-    case Operand::DataType::kFloat32:
-    case Operand::DataType::kFloat16:
-      return true;
-    case Operand::DataType::kInt32:
-    case Operand::DataType::kUint32:
-    case Operand::DataType::kInt8:
-    case Operand::DataType::kUint8:
-      return false;
-  }
-  NOTREACHED_NORETURN();
+  return DataTypeConstraint::kFloat.Has(data_type);
 }
 
 }  // namespace webnn
diff --git a/components/ml/webnn/graph_validation_utils.h b/components/ml/webnn/graph_validation_utils.h
index 8303f45..ee2307e 100644
--- a/components/ml/webnn/graph_validation_utils.h
+++ b/components/ml/webnn/graph_validation_utils.h
@@ -7,6 +7,7 @@
 
 #include <vector>
 
+#include "base/containers/enum_set.h"
 #include "base/containers/span.h"
 #include "base/types/expected.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -50,6 +51,25 @@
   std::vector<uint32_t> dimensions;
 };
 
+// TODO(crbug.com/1273291): Use the data type constraint in service side to
+// validate operators.
+using DataTypeConstraintSet = base::EnumSet<Operand::DataType,
+                                            Operand::DataType::kFloat32,
+                                            Operand::DataType::kUint8>;
+
+namespace DataTypeConstraint {
+
+static constexpr DataTypeConstraintSet kFloat = {Operand::DataType::kFloat32,
+                                                 Operand::DataType::kFloat16};
+
+static constexpr DataTypeConstraintSet kSignedInteger = {
+    Operand::DataType::kInt32, Operand::DataType::kInt8};
+
+}  // namespace DataTypeConstraint
+
+std::string DataTypeConstraintToString(
+    const DataTypeConstraintSet& constraint_set);
+
 // Represents the `MLInputOperandLayout` that specifies the layout format of
 // the input tensor. N is the batch, C is input channels, H is height and W is
 // the width of the tensor.
diff --git a/components/named_mojo_ipc_server/named_mojo_ipc_util.h b/components/named_mojo_ipc_server/named_mojo_ipc_util.h
index 9cf58c25..8c83d2c2 100644
--- a/components/named_mojo_ipc_server/named_mojo_ipc_util.h
+++ b/components/named_mojo_ipc_server/named_mojo_ipc_util.h
@@ -5,7 +5,7 @@
 #ifndef COMPONENTS_NAMED_MOJO_IPC_SERVER_NAMED_MOJO_IPC_UTIL_H_
 #define COMPONENTS_NAMED_MOJO_IPC_SERVER_NAMED_MOJO_IPC_UTIL_H_
 
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "mojo/public/cpp/platform/named_platform_channel.h"
 
 namespace named_mojo_ipc_server {
diff --git a/components/omnibox/browser/autocomplete_provider.cc b/components/omnibox/browser/autocomplete_provider.cc
index 293d5e5d..f452741 100644
--- a/components/omnibox/browser/autocomplete_provider.cc
+++ b/components/omnibox/browser/autocomplete_provider.cc
@@ -7,6 +7,7 @@
 #include <algorithm>
 #include <string>
 
+#include "base/notreached.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/trace_event/memory_usage_estimator.h"
@@ -180,7 +181,13 @@
       //   the provider in the proto and histograms.
       return metrics::OmniboxEventProto::SEARCH;
     default:
-      NOTREACHED() << "Unhandled AutocompleteProvider::Type " << type_;
+      // TODO(crbug.com/1499235) This was a NOTREACHED that we converted to help
+      //   debug crbug.com/1499235 since NOTREACHED's don't log their message in
+      //   crash reports. Should be reverted back to a NOTREACHED or
+      //   NOTREACHED_NORETURN if their logs eventually begin being logged to
+      //   crash reports.
+      DUMP_WILL_BE_NOTREACHED_NORETURN()
+          << "[NOTREACHED] Unhandled AutocompleteProvider::Type " << type_;
       return metrics::OmniboxEventProto::UNKNOWN_PROVIDER;
   }
 }
diff --git a/components/omnibox/browser/document_suggestions_service_unittest.cc b/components/omnibox/browser/document_suggestions_service_unittest.cc
index d71cb9e..2f0734ba 100644
--- a/components/omnibox/browser/document_suggestions_service_unittest.cc
+++ b/components/omnibox/browser/document_suggestions_service_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/metrics/field_trial.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
diff --git a/components/omnibox/browser/shortcuts_backend.cc b/components/omnibox/browser/shortcuts_backend.cc
index e48d1e9..ae1dadd1 100644
--- a/components/omnibox/browser/shortcuts_backend.cc
+++ b/components/omnibox/browser/shortcuts_backend.cc
@@ -17,7 +17,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/ranges/algorithm.h"
 #include "base/strings/strcat.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/single_thread_task_runner.h"
diff --git a/components/omnibox/browser/tailored_word_break_iterator.cc b/components/omnibox/browser/tailored_word_break_iterator.cc
index 26b20a3..43fd90a 100644
--- a/components/omnibox/browser/tailored_word_break_iterator.cc
+++ b/components/omnibox/browser/tailored_word_break_iterator.cc
@@ -6,6 +6,7 @@
 
 #include <string>
 
+#include "base/check.h"
 #include "base/i18n/break_iterator.h"
 #include "base/strings/string_piece.h"
 
diff --git a/components/omnibox/browser/tailored_word_break_iterator.h b/components/omnibox/browser/tailored_word_break_iterator.h
index b0a44b0..51071f56 100644
--- a/components/omnibox/browser/tailored_word_break_iterator.h
+++ b/components/omnibox/browser/tailored_word_break_iterator.h
@@ -8,7 +8,7 @@
 #include <string>
 
 #include "base/i18n/break_iterator.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 
 // Breaks on an underscore and numbers. Otherwise, it behaves like its parent
 // class with `BreakIterator::BREAK_WORD`.
diff --git a/components/optimization_guide/core/model_execution/model_execution_manager.cc b/components/optimization_guide/core/model_execution/model_execution_manager.cc
index 91d3020..02907b34 100644
--- a/components/optimization_guide/core/model_execution/model_execution_manager.cc
+++ b/components/optimization_guide/core/model_execution/model_execution_manager.cc
@@ -5,6 +5,7 @@
 #include "components/optimization_guide/core/model_execution/model_execution_manager.h"
 
 #include "base/command_line.h"
+#include "base/strings/stringprintf.h"
 #include "components/optimization_guide/core/model_execution/model_execution_fetcher.h"
 #include "components/optimization_guide/core/model_execution/on_device_model_execution_config_interpreter.h"
 #include "components/optimization_guide/core/model_execution/on_device_model_service_controller.h"
@@ -13,6 +14,8 @@
 #include "components/optimization_guide/core/model_util.h"
 #include "components/optimization_guide/core/optimization_guide_constants.h"
 #include "components/optimization_guide/core/optimization_guide_logger.h"
+#include "components/optimization_guide/core/optimization_metadata.h"
+#include "components/optimization_guide/proto/common_types.pb.h"
 #include "net/base/url_util.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 
@@ -20,6 +23,35 @@
 
 namespace {
 
+class ScopedModelExecutionResponseLogger {
+ public:
+  ScopedModelExecutionResponseLogger(
+      proto::ModelExecutionFeature feature,
+      OptimizationGuideLogger* optimization_guide_logger)
+      : feature_(feature),
+        optimization_guide_logger_(optimization_guide_logger) {}
+
+  ~ScopedModelExecutionResponseLogger() {
+    if (!optimization_guide_logger_->ShouldEnableDebugLogs()) {
+      return;
+    }
+    OPTIMIZATION_GUIDE_LOGGER(
+        optimization_guide_common::mojom::LogSource::MODEL_EXECUTION,
+        optimization_guide_logger_)
+        << "OnModelExecutionResponse - Feature : "
+        << proto::ModelExecutionFeature_Name(feature_) << " " << message_;
+  }
+
+  void set_message(const std::string& message) { message_ = message; }
+
+ private:
+  proto::ModelExecutionFeature feature_;
+  std::string message_;
+
+  // Not owned. Guaranteed to outlive |this| scoped object.
+  raw_ptr<OptimizationGuideLogger> optimization_guide_logger_;
+};
+
 // Returns the URL endpoint for the model execution service.
 GURL GetModelExecutionServiceURL() {
   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
@@ -84,6 +116,47 @@
     return;
   }
 
+  if (optimization_guide_logger_->ShouldEnableDebugLogs()) {
+    OPTIMIZATION_GUIDE_LOGGER(
+        optimization_guide_common::mojom::LogSource::MODEL_EXECUTION,
+        optimization_guide_logger_)
+        << "ExecuteModel: " << proto::ModelExecutionFeature_Name(feature);
+    switch (feature) {
+      case proto::ModelExecutionFeature::MODEL_EXECUTION_FEATURE_UNSPECIFIED: {
+        break;
+      }
+      case proto::ModelExecutionFeature::MODEL_EXECUTION_FEATURE_COMPOSE: {
+        // TOOD(b/309486492): Add logging for request/response for compose.
+        break;
+      }
+      case proto::ModelExecutionFeature::
+          MODEL_EXECUTION_FEATURE_TAB_ORGANIZATION: {
+        proto::Any any;
+        any.set_type_url(request_metadata.GetTypeName());
+        request_metadata.SerializeToString(any.mutable_value());
+        auto tab_request = optimization_guide::ParsedAnyMetadata<
+            optimization_guide::proto::TabOrganizationRequest>(any);
+        std::string titles = "";
+        for (const auto& tab : tab_request->tabs()) {
+          titles += base::StringPrintf("%s\"%s\"", titles.empty() ? "" : ",",
+                                       tab.title().c_str());
+        }
+        OPTIMIZATION_GUIDE_LOGGER(
+            optimization_guide_common::mojom::LogSource::MODEL_EXECUTION,
+            optimization_guide_logger_)
+            << "TabOrganization Request: "
+            << base::StringPrintf("{\"titles\" : [%s]}", titles.c_str());
+
+        break;
+      }
+      case proto::ModelExecutionFeature::
+          MODEL_EXECUTION_FEATURE_WALLPAPER_SEARCH: {
+        // TOOD(b/309486807): Add logging for request/response for wallpapers.
+        break;
+      }
+    }
+  }
+
   auto fetcher_it = active_model_execution_fetchers_.emplace(
       std::piecewise_construct, std::forward_as_tuple(feature),
       std::forward_as_tuple(url_loader_factory_, model_execution_service_url_,
@@ -101,12 +174,22 @@
     base::expected<const proto::ExecuteResponse,
                    OptimizationGuideModelExecutionError> execute_response) {
   active_model_execution_fetchers_.erase(feature);
+  ScopedModelExecutionResponseLogger scoped_logger(feature,
+                                                   optimization_guide_logger_);
   if (!execute_response.has_value()) {
+    scoped_logger.set_message("Error: No Response");
     std::move(callback).Run(base::unexpected(execute_response.error()),
                             nullptr);
     return;
   }
+
+  if (execute_response->has_error_message()) {
+    scoped_logger.set_message(base::StringPrintf(
+        "Error: %s", execute_response->error_message().c_str()));
+  }
+
   if (!execute_response->has_response_metadata()) {
+    scoped_logger.set_message("Error: No Response Metadata");
     std::move(callback).Run(
         base::unexpected(
             OptimizationGuideModelExecutionError::FromModelExecutionError(
@@ -114,6 +197,50 @@
         nullptr);
     return;
   }
+
+  if (optimization_guide_logger_->ShouldEnableDebugLogs()) {
+    switch (feature) {
+      case proto::ModelExecutionFeature::MODEL_EXECUTION_FEATURE_UNSPECIFIED: {
+        break;
+      }
+      case proto::ModelExecutionFeature::MODEL_EXECUTION_FEATURE_COMPOSE: {
+        // TOOD(b/309486492): Add logging for request/response for compose.
+        break;
+      }
+      case proto::ModelExecutionFeature::
+          MODEL_EXECUTION_FEATURE_TAB_ORGANIZATION: {
+        std::string message = "";
+        auto tab_response = optimization_guide::ParsedAnyMetadata<
+            optimization_guide::proto::TabOrganizationResponse>(
+            execute_response->response_metadata());
+        message += "Response: [";
+        int group_cnt = 0;
+        for (const auto& tab_organization : tab_response->tab_organizations()) {
+          std::string tab_titles = "";
+          for (const auto& tab : tab_organization.tabs()) {
+            tab_titles +=
+                base::StringPrintf("%s\" %s \"", tab_titles.empty() ? "" : ",",
+                                   tab.title().c_str());
+          }
+          message += base::StringPrintf(
+              "%s{"
+              "\"label\": \"%s\", "
+              "\"tabs\": [%s] }",
+              group_cnt > 0 ? "," : "", tab_organization.label().c_str(),
+              tab_titles.c_str());
+          group_cnt += 1;
+        }
+        message += "]";
+        scoped_logger.set_message(message);
+        break;
+      }
+      case proto::ModelExecutionFeature::
+          MODEL_EXECUTION_FEATURE_WALLPAPER_SEARCH: {
+        // TOOD(b/309486807): Add logging for request/response for wallpapers.
+        break;
+      }
+    }
+  }
   std::move(callback).Run(base::ok(execute_response->response_metadata()),
                           nullptr);
 }
diff --git a/components/optimization_guide/core/model_execution/model_execution_manager_unittest.cc b/components/optimization_guide/core/model_execution/model_execution_manager_unittest.cc
index ab09cd7a..72b1a41e 100644
--- a/components/optimization_guide/core/model_execution/model_execution_manager_unittest.cc
+++ b/components/optimization_guide/core/model_execution/model_execution_manager_unittest.cc
@@ -10,7 +10,9 @@
 #include "base/test/test.pb.h"
 #include "components/optimization_guide/core/model_execution/on_device_model_service_controller.h"
 #include "components/optimization_guide/core/optimization_guide_logger.h"
+#include "components/optimization_guide/core/optimization_guide_util.h"
 #include "components/signin/public/identity_manager/identity_test_environment.h"
+#include "components/variations/scoped_variations_ids_provider.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
 #include "services/network/test/test_url_loader_factory.h"
@@ -18,8 +20,27 @@
 
 namespace optimization_guide {
 
+using base::test::TestMessage;
+
 namespace {
 
+constexpr char kOptimizationGuideServiceUrl[] =
+    "https://optimization-guide-server.com/?key=foo_key";
+
+TestMessage BuildTestMessage(const std::string& test_message_str) {
+  TestMessage test_message;
+  test_message.set_test(test_message_str);
+  return test_message;
+}
+
+proto::ExecuteResponse BuildTestExecuteResponse(const TestMessage& message) {
+  proto::ExecuteResponse execute_response;
+  proto::Any* any_metadata = execute_response.mutable_response_metadata();
+  any_metadata->set_type_url("type.googleapis.com/" + message.GetTypeName());
+  message.SerializeToString(any_metadata->mutable_value());
+  return execute_response;
+}
+
 class ModelExecutionManagerTest : public testing::Test {
  public:
   ModelExecutionManagerTest() = default;
@@ -35,6 +56,25 @@
         &optimization_guide_logger_);
   }
 
+  bool SimulateResponse(const std::string& content,
+                        net::HttpStatusCode http_status) {
+    return test_url_loader_factory_.SimulateResponseForPendingRequest(
+        kOptimizationGuideServiceUrl, content, http_status,
+        network::TestURLLoaderFactory::kUrlMatchPrefix);
+  }
+
+  bool SimulateSuccessfulResponse() {
+    std::string serialized_response;
+    proto::ExecuteResponse execute_response =
+        BuildTestExecuteResponse(BuildTestMessage("foo response"));
+    execute_response.SerializeToString(&serialized_response);
+    return SimulateResponse(serialized_response, net::HTTP_OK);
+  }
+
+  signin::IdentityTestEnvironment* identity_test_env() {
+    return &identity_test_env_;
+  }
+
   ModelExecutionManager* model_execution_manager() {
     return model_execution_manager_.get();
   }
@@ -42,6 +82,8 @@
  private:
   base::test::TaskEnvironment task_environment_;
   signin::IdentityTestEnvironment identity_test_env_;
+  variations::ScopedVariationsIdsProvider scoped_variations_ids_provider_{
+      variations::VariationsIdsProvider::Mode::kUseSignedInState};
   scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
   network::TestURLLoaderFactory test_url_loader_factory_;
   OptimizationGuideLogger optimization_guide_logger_;
@@ -58,14 +100,39 @@
           [](base::RunLoop* run_loop,
              OptimizationGuideModelExecutionResult result,
              std::unique_ptr<ModelQualityLogEntry> log_entry) {
-            ASSERT_FALSE(result.has_value());
-            ASSERT_EQ(log_entry.get(), nullptr);
+            EXPECT_FALSE(result.has_value());
+            EXPECT_EQ(log_entry.get(), nullptr);
             run_loop->Quit();
           },
           &run_loop));
   run_loop.RunUntilIdle();
 }
 
+TEST_F(ModelExecutionManagerTest, ExecuteModelWithUserSignIn) {
+  base::test::TestMessage test_message;
+  test_message.set_test("some test");
+  base::RunLoop run_loop;
+  identity_test_env()->MakePrimaryAccountAvailable(
+      "test_email", signin::ConsentLevel::kSignin);
+  model_execution_manager()->ExecuteModel(
+      proto::MODEL_EXECUTION_FEATURE_COMPOSE, test_message,
+      base::BindOnce(
+          [](base::RunLoop* run_loop,
+             OptimizationGuideModelExecutionResult result,
+             std::unique_ptr<ModelQualityLogEntry> log_entry) {
+            EXPECT_TRUE(result.has_value());
+            EXPECT_EQ("foo response",
+                      ParsedAnyMetadata<TestMessage>(result.value())->test());
+            EXPECT_EQ(log_entry.get(), nullptr);
+            run_loop->Quit();
+          },
+          &run_loop));
+  identity_test_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
+      "access_token", base::Time::Max());
+  SimulateSuccessfulResponse();
+  run_loop.RunUntilIdle();
+}
+
 }  // namespace
 
 }  // namespace optimization_guide
diff --git a/components/optimization_guide/core/optimization_guide_common.mojom b/components/optimization_guide/core/optimization_guide_common.mojom
index 7cdd2fc..8b256fd4 100644
--- a/components/optimization_guide/core/optimization_guide_common.mojom
+++ b/components/optimization_guide/core/optimization_guide_common.mojom
@@ -14,4 +14,5 @@
   PAGE_CONTENT_ANNOTATIONS,
   HINTS_NOTIFICATIONS,
   TEXT_CLASSIFIER,
+  MODEL_EXECUTION,
 };
diff --git a/components/optimization_guide/optimization_guide_internals/resources/optimization_guide_internals.ts b/components/optimization_guide/optimization_guide_internals/resources/optimization_guide_internals.ts
index dcdbef24..ad21b32 100644
--- a/components/optimization_guide/optimization_guide_internals/resources/optimization_guide_internals.ts
+++ b/components/optimization_guide/optimization_guide_internals/resources/optimization_guide_internals.ts
@@ -91,6 +91,9 @@
   if (logSource == 5) {
     return 'TEXT_CLASSIFIER';
   }
+  if (logSource == 6) {
+    return 'MODEL_EXECUTION';
+  }
   return logSource.toString();
 }
 
diff --git a/components/password_manager/core/browser/affiliation/affiliations_prefetcher.cc b/components/password_manager/core/browser/affiliation/affiliations_prefetcher.cc
index aab4b843..5b8a802 100644
--- a/components/password_manager/core/browser/affiliation/affiliations_prefetcher.cc
+++ b/components/password_manager/core/browser/affiliation/affiliations_prefetcher.cc
@@ -73,6 +73,17 @@
   pending_initializations_.clear();
 }
 
+void AffiliationsPrefetcher::DisablePrefetching() {
+  // Don't do anything if prefetching was canceled already.
+  if (is_prefetching_canceled_) {
+    return;
+  }
+
+  is_prefetching_canceled_ = true;
+  // Clear existing cache.
+  affiliation_service_->KeepPrefetchForFacets({});
+}
+
 void AffiliationsPrefetcher::OnLoginsChanged(
     PasswordStoreInterface* /*store*/,
     const PasswordStoreChangeList& changes) {
@@ -155,6 +166,11 @@
 }
 
 void AffiliationsPrefetcher::InitializeWithPasswordStores() {
+  // Don't do anything if prefetching is canceled.
+  if (is_prefetching_canceled_) {
+    return;
+  }
+
   // If no calls to RegisterPasswordStore happened before
   // |kInitializationDelayOnStartup| return early.
   if (pending_initializations_.empty()) {
diff --git a/components/password_manager/core/browser/affiliation/affiliations_prefetcher.h b/components/password_manager/core/browser/affiliation/affiliations_prefetcher.h
index fd36f99..ec5de4d3 100644
--- a/components/password_manager/core/browser/affiliation/affiliations_prefetcher.h
+++ b/components/password_manager/core/browser/affiliation/affiliations_prefetcher.h
@@ -35,6 +35,9 @@
   // KeyedService:
   void Shutdown() override;
 
+  // Disables affiliations prefetching and clears all the existing cache.
+  void DisablePrefetching();
+
  private:
   // PasswordStoreInterface::Observer:
   void OnLoginsChanged(PasswordStoreInterface* store,
@@ -69,6 +72,9 @@
   // |password_stores_|.
   bool is_ready_ = false;
 
+  // Whether this class should continue prefetching passwords.
+  bool is_prefetching_canceled_ = false;
+
   base::WeakPtrFactory<AffiliationsPrefetcher> weak_ptr_factory_{this};
 };
 
diff --git a/components/password_manager/core/browser/affiliation/affiliations_prefetcher_unittest.cc b/components/password_manager/core/browser/affiliation/affiliations_prefetcher_unittest.cc
index ea15f5f..be4fba7 100644
--- a/components/password_manager/core/browser/affiliation/affiliations_prefetcher_unittest.cc
+++ b/components/password_manager/core/browser/affiliation/affiliations_prefetcher_unittest.cc
@@ -447,6 +447,37 @@
       ->OnLoginsRetained(nullptr, forms);
 }
 
+TEST_F(AffiliationsPrefetcherTest, TestDisablePrefetch) {
+  AddLoginAndWait(password_store(),
+                  GetTestAndroidCredentials(kTestWebFacetURIAlpha1));
+  prefetcher()->RegisterPasswordStore(password_store());
+
+  ExpectKeepPrefetchForFacets({});
+  prefetcher()->DisablePrefetching();
+
+  // KeepPrefetchForFacets is no longer called even if calling
+  // DisablePrefetching() again.
+  EXPECT_CALL(*mock_affiliation_service(), KeepPrefetchForFacets).Times(0);
+  prefetcher()->DisablePrefetching();
+
+  RunUntilIdle();
+  FastForwardBy(kInitializationDelayOnStartup);
+}
+
+TEST_F(AffiliationsPrefetcherTest, TestDisablePrefetchWithLoginsChanges) {
+  prefetcher()->RegisterPasswordStore(password_store());
+
+  ExpectKeepPrefetchForFacets({});
+  prefetcher()->DisablePrefetching();
+
+  RunUntilIdle();
+  FastForwardBy(kInitializationDelayOnStartup);
+
+  EXPECT_CALL(*mock_affiliation_service(), Prefetch).Times(0);
+  AddLoginAndWait(password_store(),
+                  GetTestAndroidCredentials(kTestWebFacetURIAlpha1));
+}
+
 class AffiliationsPrefetcherWithTwoStoresTest
     : public AffiliationsPrefetcherTest {
  protected:
diff --git a/components/password_manager/core/browser/leak_detection/encryption_utils.h b/components/password_manager/core/browser/leak_detection/encryption_utils.h
index a23dd846..69cb907 100644
--- a/components/password_manager/core/browser/leak_detection/encryption_utils.h
+++ b/components/password_manager/core/browser/leak_detection/encryption_utils.h
@@ -7,7 +7,7 @@
 
 #include <string>
 
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace password_manager {
diff --git a/components/password_manager/core/browser/leak_detection/leak_detection_request_utils.h b/components/password_manager/core/browser/leak_detection/leak_detection_request_utils.h
index db820b5..7e48cdac 100644
--- a/components/password_manager/core/browser/leak_detection/leak_detection_request_utils.h
+++ b/components/password_manager/core/browser/leak_detection/leak_detection_request_utils.h
@@ -6,7 +6,7 @@
 #define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_LEAK_DETECTION_LEAK_DETECTION_REQUEST_UTILS_H_
 
 #include "base/functional/callback.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/task/cancelable_task_tracker.h"
 #include "base/task/task_runner.h"
 #include "components/signin/public/identity_manager/access_token_fetcher.h"
diff --git a/components/password_manager/core/browser/password_autofill_manager.cc b/components/password_manager/core/browser/password_autofill_manager.cc
index 14ada221..951bdbc3 100644
--- a/components/password_manager/core/browser/password_autofill_manager.cc
+++ b/components/password_manager/core/browser/password_autofill_manager.cc
@@ -97,8 +97,9 @@
 
 // Returns a string representing the icon of either the account store or the
 // local password store.
-std::string CreateStoreIcon(bool for_account_store) {
-  return for_account_store ? "google" : std::string();
+autofill::Suggestion::Icon CreateStoreIcon(bool for_account_store) {
+  return for_account_store ? autofill::Suggestion::Icon::kGoogle
+                           : autofill::Suggestion::Icon::kNoIcon;
 }
 
 // If |field_suggestion| matches |field_content|, creates a Suggestion out of it
@@ -148,7 +149,7 @@
     }
     suggestion.custom_icon = custom_icon;
     // The UI code will pick up an icon from the resources based on the string.
-    suggestion.icon = "globeIcon";
+    suggestion.icon = autofill::Suggestion::Icon::kGlobe;
     suggestion.trailing_icon = CreateStoreIcon(from_account_store);
     suggestions->push_back(suggestion);
   }
@@ -224,10 +225,10 @@
   if (base::FeatureList::IsEnabled(
           password_manager::features::kEnablePasswordsAccountStorage)) {
     // The UI code will pick up an icon from the resources based on the string.
-    suggestion.icon = "settingsIcon";
+    suggestion.icon = autofill::Suggestion::Icon::kSettings;
   }
   // The UI code will pick up an icon from the resources based on the string.
-  suggestion.trailing_icon = "googlePasswordManager";
+  suggestion.trailing_icon = autofill::Suggestion::Icon::kGooglePasswordManager;
   suggestions->push_back(std::move(suggestion));
 }
 
@@ -236,7 +237,7 @@
   autofill::Suggestion suggestion(l10n_util::GetStringUTF16(
       listed_passkeys ? IDS_PASSWORD_MANAGER_USE_DIFFERENT_PASSKEY
                       : IDS_PASSWORD_MANAGER_USE_PASSKEY));
-  suggestion.icon = "device";
+  suggestion.icon = autofill::Suggestion::Icon::kDevice;
   suggestion.popup_item_id =
       autofill::PopupItemId::kWebauthnSignInWithAnotherDevice;
   return suggestion;
@@ -247,7 +248,7 @@
   autofill::Suggestion suggestion(
       l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_GENERATE_PASSWORD));
   // The UI code will pick up an icon from the resources based on the string.
-  suggestion.icon = "keyIcon";
+  suggestion.icon = autofill::Suggestion::Icon::kKey;
   suggestion.popup_item_id = autofill::PopupItemId::kGeneratePasswordEntry;
   return suggestion;
 }
@@ -265,7 +266,7 @@
           : IDS_PASSWORD_MANAGER_OPT_INTO_ACCOUNT_STORE));
   suggestion.popup_item_id =
       autofill::PopupItemId::kPasswordAccountStorageOptIn;
-  suggestion.icon = "google";
+  suggestion.icon = autofill::Suggestion::Icon::kGoogle;
   return suggestion;
 }
 
@@ -275,7 +276,7 @@
       l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_GENERATE_PASSWORD));
   suggestion.popup_item_id =
       autofill::PopupItemId::kPasswordAccountStorageOptInAndGenerate;
-  suggestion.icon = "keyIcon";
+  suggestion.icon = autofill::Suggestion::Icon::kKey;
   return suggestion;
 }
 
@@ -285,7 +286,7 @@
       l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_RE_SIGNIN_ACCOUNT_STORE));
   suggestion.popup_item_id =
       autofill::PopupItemId::kPasswordAccountStorageReSignin;
-  suggestion.icon = "google";
+  suggestion.icon = autofill::Suggestion::Icon::kGoogle;
   return suggestion;
 }
 
@@ -295,7 +296,7 @@
       l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_NO_ACCOUNT_STORE_MATCHES));
   suggestion.popup_item_id =
       autofill::PopupItemId::kPasswordAccountStorageEmpty;
-  suggestion.icon = "empty";
+  suggestion.icon = autofill::Suggestion::Icon::kEmpty;
   return suggestion;
 }
 
@@ -732,7 +733,7 @@
         *delegate->GetPasskeys(), std::back_inserter(suggestions),
         [this](const auto& passkey) {
           autofill::Suggestion suggestion(ToUsernameString(passkey.username()));
-          suggestion.icon = "globeIcon";
+          suggestion.icon = autofill::Suggestion::Icon::kGlobe;
           suggestion.popup_item_id = autofill::PopupItemId::kWebauthnCredential;
           suggestion.custom_icon = page_favicon_;
           suggestion.payload = autofill::Suggestion::BackendId(
diff --git a/components/password_manager/core/browser/password_autofill_manager_unittest.cc b/components/password_manager/core/browser/password_autofill_manager_unittest.cc
index fd868cc..9541d368 100644
--- a/components/password_manager/core/browser/password_autofill_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_autofill_manager_unittest.cc
@@ -249,26 +249,30 @@
     bool has_re_signin) {
   std::vector<Suggestion> suggestions;
   suggestions.emplace_back(
-      /*value=*/"User1", /*label=*/"PW1", /*icon=*/"",
+      /*value=*/"User1", /*label=*/"PW1", /*icon=*/Suggestion::Icon::kNoIcon,
       /*popup_item_id=*/autofill::PopupItemId::kPasswordEntry);
   suggestions.emplace_back(
-      /*value=*/"Show all pwds", /*label=*/"", /*icon=*/"",
+      /*value=*/"Show all pwds", /*label=*/"",
+      /*icon=*/Suggestion::Icon::kNoIcon,
       /*popup_item_id=*/autofill::PopupItemId::kAllSavedPasswordsEntry);
   if (has_opt_in_and_fill) {
     suggestions.emplace_back(
-        /*value=*/"Unlock passwords and fill", /*label=*/"", /*icon=*/"",
+        /*value=*/"Unlock passwords and fill", /*label=*/"",
+        /*icon=*/Suggestion::Icon::kNoIcon,
         /*popup_item_id=*/
         autofill::PopupItemId::kPasswordAccountStorageOptIn);
   }
   if (has_opt_in_and_generate) {
     suggestions.emplace_back(
-        /*value=*/"Unlock passwords and generate", /*label=*/"", /*icon=*/"",
+        /*value=*/"Unlock passwords and generate", /*label=*/"",
+        /*icon=*/Suggestion::Icon::kNoIcon,
         /*popup_item_id=*/
         autofill::PopupItemId::kPasswordAccountStorageOptInAndGenerate);
   }
   if (has_re_signin) {
     suggestions.emplace_back(
-        /*value=*/"Sign in to access passwords", /*label=*/"", /*icon=*/"",
+        /*value=*/"Sign in to access passwords", /*label=*/"",
+        /*icon=*/Suggestion::Icon::kNoIcon,
         /*popup_item_id=*/
         autofill::PopupItemId::kPasswordAccountStorageReSignin);
   }
@@ -352,15 +356,14 @@
     return l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_MANAGE_PASSWORDS);
   }
 
-  std::string GetManagePasswordsIcon() {
+  Suggestion::Icon GetManagePasswordsIcon() {
     // The "Manage passwords" entry only has an icon if
     // kEnablePasswordsAccountStorage is enabled.
-    std::string settings_icon;
     if (base::FeatureList::IsEnabled(
             password_manager::features::kEnablePasswordsAccountStorage)) {
-      return "settingsIcon";
+      return Suggestion::Icon::kSettings;
     }
-    return std::string();
+    return Suggestion::Icon::kNoIcon;
   }
 
   void ExpectAndAllowAuthentication(
@@ -957,7 +960,8 @@
   // Only the unlock button was available. After being clicked, it's in a
   // loading state which the DeleteFillData() call will end.
   Suggestion unlock_suggestion(
-      /*main_text=*/"Unlock passwords and fill", /*label=*/"", /*icon=*/"",
+      /*main_text=*/"Unlock passwords and fill", /*label=*/"",
+      /*icon=*/Suggestion::Icon::kNoIcon,
       /*popup_item_id=*/
       autofill::PopupItemId::kPasswordAccountStorageOptIn);
   unlock_suggestion.is_loading = Suggestion::IsLoading(true);
@@ -1379,13 +1383,14 @@
   histograms.ExpectUniqueSample(
       kDropdownShownHistogram,
       metrics_util::PasswordDropdownState::kStandardGenerate, 1);
-  EXPECT_THAT(open_args.suggestions,
-              SuggestionVectorIconsAre("globeIcon", "keyIcon",
+  EXPECT_THAT(
+      open_args.suggestions,
+      SuggestionVectorIconsAre(Suggestion::Icon::kGlobe, Suggestion::Icon::kKey,
 #if !BUILDFLAG(IS_ANDROID)
-                                       "",
+                               Suggestion::Icon::kNoIcon,
 #endif
 
-                                       GetManagePasswordsIcon()));
+                               GetManagePasswordsIcon()));
   EXPECT_THAT(
       open_args.suggestions,
       SuggestionVectorMainTextsAre(
@@ -1438,9 +1443,9 @@
           element_bounds, base::i18n::RIGHT_TO_LEFT,
           /*show_password_suggestions=*/false));
   EXPECT_THAT(open_args.suggestions,
-              SuggestionVectorIconsAre("keyIcon",
+              SuggestionVectorIconsAre(Suggestion::Icon::kKey,
 #if !BUILDFLAG(IS_ANDROID)
-                                       "",
+                                       Suggestion::Icon::kNoIcon,
 #endif
                                        GetManagePasswordsIcon()));
 
@@ -1517,7 +1522,8 @@
       autofill::ShowPasswordSuggestionsOptions(), element_bounds);
   ASSERT_THAT(open_args.suggestions.size(),
               testing::Ge(1u));  // No footer on Android.
-  EXPECT_THAT(open_args.suggestions[0].trailing_icon, "google");
+  EXPECT_THAT(open_args.suggestions[0].trailing_icon,
+              Suggestion::Icon::kGoogle);
   EXPECT_EQ(open_args.trigger_source,
             autofill::AutofillSuggestionTriggerSource::kPasswordManager);
 }
diff --git a/components/password_manager/core/browser/password_hash_data.h b/components/password_manager/core/browser/password_hash_data.h
index bb8c1b2..6ac7934 100644
--- a/components/password_manager/core/browser/password_hash_data.h
+++ b/components/password_manager/core/browser/password_hash_data.h
@@ -9,7 +9,7 @@
 
 #include <string>
 
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 
 namespace password_manager {
 
diff --git a/components/password_manager/core/browser/password_store/password_store_backend_metrics_recorder.h b/components/password_manager/core/browser/password_store/password_store_backend_metrics_recorder.h
index c14c85e..6ef9362 100644
--- a/components/password_manager/core/browser/password_store/password_store_backend_metrics_recorder.h
+++ b/components/password_manager/core/browser/password_store/password_store_backend_metrics_recorder.h
@@ -7,7 +7,7 @@
 
 #include <string>
 
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "base/types/strong_alias.h"
 #include "components/password_manager/core/browser/password_store/android_backend_error.h"
diff --git a/components/password_manager/core/browser/ui/bulk_leak_check_service_adapter_unittest.cc b/components/password_manager/core/browser/ui/bulk_leak_check_service_adapter_unittest.cc
index f3fbe91..2d71c90 100644
--- a/components/password_manager/core/browser/ui/bulk_leak_check_service_adapter_unittest.cc
+++ b/components/password_manager/core/browser/ui/bulk_leak_check_service_adapter_unittest.cc
@@ -12,7 +12,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/ranges/algorithm.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/gmock_move_support.h"
 #include "base/test/task_environment.h"
diff --git a/components/password_manager/core/browser/ui/insecure_credentials_manager_unittest.cc b/components/password_manager/core/browser/ui/insecure_credentials_manager_unittest.cc
index 8fba611..9d8b902 100644
--- a/components/password_manager/core/browser/ui/insecure_credentials_manager_unittest.cc
+++ b/components/password_manager/core/browser/ui/insecure_credentials_manager_unittest.cc
@@ -5,7 +5,7 @@
 #include "components/password_manager/core/browser/ui/insecure_credentials_manager.h"
 
 #include "base/memory/scoped_refptr.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/gmock_callback_support.h"
 #include "base/test/metrics/histogram_tester.h"
diff --git a/components/password_manager/core/browser/ui/saved_passwords_presenter.h b/components/password_manager/core/browser/ui/saved_passwords_presenter.h
index 32b767c..6f48e6a 100644
--- a/components/password_manager/core/browser/ui/saved_passwords_presenter.h
+++ b/components/password_manager/core/browser/ui/saved_passwords_presenter.h
@@ -13,7 +13,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "base/scoped_observation.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "components/password_manager/core/browser/password_store_consumer.h"
 #include "components/password_manager/core/browser/password_store_interface.h"
 #include "components/password_manager/core/browser/ui/affiliated_group.h"
diff --git a/components/password_manager/core/browser/ui/weak_check_utility.h b/components/password_manager/core/browser/ui/weak_check_utility.h
index b8223669..551c433 100644
--- a/components/password_manager/core/browser/ui/weak_check_utility.h
+++ b/components/password_manager/core/browser/ui/weak_check_utility.h
@@ -8,7 +8,7 @@
 #include <string>
 
 #include "base/containers/flat_set.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/types/strong_alias.h"
 
 namespace password_manager {
diff --git a/components/payments/content/payment_event_response_util.h b/components/payments/content/payment_event_response_util.h
index 1007e84..95c8293 100644
--- a/components/payments/content/payment_event_response_util.h
+++ b/components/payments/content/payment_event_response_util.h
@@ -5,7 +5,7 @@
 #ifndef COMPONENTS_PAYMENTS_CONTENT_PAYMENT_EVENT_RESPONSE_UTIL_H_
 #define COMPONENTS_PAYMENTS_CONTENT_PAYMENT_EVENT_RESPONSE_UTIL_H_
 
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "third_party/blink/public/mojom/payments/payment_app.mojom.h"
 
 namespace payments {
diff --git a/components/performance_manager/public/resource_attribution/cpu_measurement_delegate.h b/components/performance_manager/public/resource_attribution/cpu_measurement_delegate.h
index 4c4eb46..b0da569 100644
--- a/components/performance_manager/public/resource_attribution/cpu_measurement_delegate.h
+++ b/components/performance_manager/public/resource_attribution/cpu_measurement_delegate.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/functional/callback_forward.h"
 #include "base/time/time.h"
 
 namespace performance_manager {
@@ -20,17 +19,19 @@
 // A shim that Resource Attribution queries use to request CPU measurements for
 // a process. A new CPUMeasurementDelegate object will be created for each
 // ProcessNode to be measured. Public so that users of the API can inject a test
-// override by passing a factory callback to SetDelegateFactoryForTesting().
+// override by passing a factory object to SetDelegateFactoryForTesting().
 class CPUMeasurementDelegate {
  public:
-  using FactoryCallback =
-      base::RepeatingCallback<std::unique_ptr<CPUMeasurementDelegate>(
-          const ProcessNode*)>;
+  class Factory;
 
-  // The given `factory_callback` will be called to create a
-  // CPUMeasurementDelegate for each ProcessNode in `graph` to be measured.
-  static void SetDelegateFactoryForTesting(Graph* graph,
-                                           FactoryCallback factory_callback);
+  // The given `factory` will be used to create a CPUMeasurementDelegate for
+  // each ProcessNode in `graph` to be measured. The factory object must outlive
+  // the graph. Usually it's owned by the test harness. nullptr will cause the
+  // factory returned by GetDefaultFactory() to be used.
+  static void SetDelegateFactoryForTesting(Graph* graph, Factory* factory);
+
+  // Returns the default factory to use in production.
+  static Factory* GetDefaultFactory();
 
   CPUMeasurementDelegate() = default;
   virtual ~CPUMeasurementDelegate() = default;
@@ -40,6 +41,22 @@
   [[nodiscard]] virtual base::TimeDelta GetCumulativeCPUUsage() = 0;
 };
 
+class CPUMeasurementDelegate::Factory {
+ public:
+  virtual ~Factory() = default;
+
+  // Returns true iff a CPUMeasurementDelegate should be created for
+  // `process_node`. The production factory returns true to measure
+  // renderer processes with a valid (running) base::Process and a
+  // base::ProcessId assigned.
+  virtual bool ShouldMeasureProcess(const ProcessNode* process_node) = 0;
+
+  // Creates a CPUMeasurementDelegate for `process_node`. This should only be
+  // called if ShouldMeasureProcess(process_node) returns true.
+  virtual std::unique_ptr<CPUMeasurementDelegate> CreateDelegateForProcess(
+      const ProcessNode* process_node) = 0;
+};
+
 }  // namespace performance_manager::resource_attribution
 
 #endif  // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_RESOURCE_ATTRIBUTION_CPU_MEASUREMENT_DELEGATE_H_
diff --git a/components/performance_manager/resource_attribution/cpu_measurement_delegate.cc b/components/performance_manager/resource_attribution/cpu_measurement_delegate.cc
index 6c73009..d6ab5fb8 100644
--- a/components/performance_manager/resource_attribution/cpu_measurement_delegate.cc
+++ b/components/performance_manager/resource_attribution/cpu_measurement_delegate.cc
@@ -4,23 +4,108 @@
 
 #include "components/performance_manager/public/resource_attribution/cpu_measurement_delegate.h"
 
-#include <utility>
-
 #include "base/check.h"
+#include "base/no_destructor.h"
+#include "base/process/process.h"
+#include "base/process/process_handle.h"
+#include "base/process/process_metrics.h"
+#include "build/build_config.h"
+#include "components/performance_manager/public/graph/process_node.h"
 #include "components/performance_manager/resource_attribution/cpu_measurement_monitor.h"
 #include "components/performance_manager/resource_attribution/query_scheduler.h"
+#include "content/public/browser/browser_child_process_host.h"
+#include "content/public/common/process_type.h"
 
 namespace performance_manager::resource_attribution {
 
+namespace {
+
+// A production CPUMeasurementDelegate that measures processes with
+// base::ProcessMetrics.
+class CPUMeasurementDelegateImpl final : public CPUMeasurementDelegate {
+ public:
+  explicit CPUMeasurementDelegateImpl(const ProcessNode* process_node);
+  ~CPUMeasurementDelegateImpl() final = default;
+
+  base::TimeDelta GetCumulativeCPUUsage() final;
+
+ private:
+  std::unique_ptr<base::ProcessMetrics> process_metrics_;
+};
+
+CPUMeasurementDelegateImpl::CPUMeasurementDelegateImpl(
+    const ProcessNode* process_node) {
+  const base::ProcessHandle handle = process_node->GetProcess().Handle();
+#if BUILDFLAG(IS_MAC)
+  process_metrics_ = base::ProcessMetrics::CreateProcessMetrics(
+      handle, content::BrowserChildProcessHost::GetPortProvider());
+#else
+  process_metrics_ = base::ProcessMetrics::CreateProcessMetrics(handle);
+#endif
+}
+
+base::TimeDelta CPUMeasurementDelegateImpl::GetCumulativeCPUUsage() {
+  return process_metrics_->GetCumulativeCPUUsage();
+}
+
+// The default production factory for CPUMeasurementDelegateImpl objects.
+class CPUMeasurementDelegateFactoryImpl final
+    : public CPUMeasurementDelegate::Factory {
+ public:
+  CPUMeasurementDelegateFactoryImpl() = default;
+  ~CPUMeasurementDelegateFactoryImpl() final = default;
+
+  bool ShouldMeasureProcess(const ProcessNode* process_node) final;
+  std::unique_ptr<CPUMeasurementDelegate> CreateDelegateForProcess(
+      const ProcessNode* process_node) final;
+};
+
+bool CPUMeasurementDelegateFactoryImpl::ShouldMeasureProcess(
+    const ProcessNode* process_node) {
+  if (process_node->GetProcessType() != content::PROCESS_TYPE_RENDERER) {
+    // TODO(crbug.com/1471683): Handle other process types.
+    return false;
+  }
+  // The process start time is not available until the ProcessId is assigned.
+  if (process_node->GetProcessId() == base::kNullProcessId) {
+    return false;
+  }
+  // This can be called from OnProcessLifetimeChange after a process exits.
+  // Only handle process start notifications (which is when the pid is
+  // assigned), not exit notifications. Note the pid can be reassigned if a
+  // process dies and a new one is started for the same ProcessNode - in that
+  // case MonitorCPUUsage will reset the measurements and start monitoring the
+  // new process from scratch.
+  if (!process_node->GetProcess().IsValid()) {
+    return false;
+  }
+  return true;
+}
+
+std::unique_ptr<CPUMeasurementDelegate>
+CPUMeasurementDelegateFactoryImpl::CreateDelegateForProcess(
+    const ProcessNode* process_node) {
+  return std::make_unique<CPUMeasurementDelegateImpl>(process_node);
+}
+
+}  // namespace
+
+// static
 void CPUMeasurementDelegate::SetDelegateFactoryForTesting(
     Graph* graph,
-    FactoryCallback factory_callback) {
+    CPUMeasurementDelegate::Factory* factory) {
   auto* scheduler = QueryScheduler::GetFromGraph(graph);
   CHECK(scheduler);
   scheduler
       ->GetCPUMonitorForTesting()                   // IN-TEST
       .SetCPUMeasurementDelegateFactoryForTesting(  // IN-TEST
-          std::move(factory_callback));
+          factory ? factory : GetDefaultFactory());
+}
+
+// static
+CPUMeasurementDelegate::Factory* CPUMeasurementDelegate::GetDefaultFactory() {
+  static base::NoDestructor<CPUMeasurementDelegateFactoryImpl> default_factory;
+  return default_factory.get();
 }
 
 }  // namespace performance_manager::resource_attribution
diff --git a/components/performance_manager/resource_attribution/cpu_measurement_monitor.cc b/components/performance_manager/resource_attribution/cpu_measurement_monitor.cc
index 3ecad271..87e7e58 100644
--- a/components/performance_manager/resource_attribution/cpu_measurement_monitor.cc
+++ b/components/performance_manager/resource_attribution/cpu_measurement_monitor.cc
@@ -15,12 +15,9 @@
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
 #include "base/functional/overloaded.h"
-#include "base/process/process_handle.h"
-#include "base/process/process_metrics.h"
 #include "base/sequence_checker.h"
 #include "base/system/sys_info.h"
 #include "base/time/time.h"
-#include "build/build_config.h"
 #include "components/performance_manager/public/graph/frame_node.h"
 #include "components/performance_manager/public/graph/graph.h"
 #include "components/performance_manager/public/graph/graph_operations.h"
@@ -31,7 +28,6 @@
 #include "components/performance_manager/public/resource_attribution/frame_context.h"
 #include "components/performance_manager/public/resource_attribution/worker_context.h"
 #include "components/performance_manager/resource_attribution/graph_change.h"
-#include "content/public/browser/browser_child_process_host.h"
 #include "content/public/common/process_type.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
 
@@ -39,42 +35,6 @@
 
 namespace {
 
-class CPUMeasurementDelegateImpl final : public CPUMeasurementDelegate {
- public:
-  // Default factory function.
-  static std::unique_ptr<CPUMeasurementDelegate> Create(
-      const ProcessNode* process_node) {
-    return std::make_unique<CPUMeasurementDelegateImpl>(process_node);
-  }
-
-  explicit CPUMeasurementDelegateImpl(const ProcessNode* process_node);
-  ~CPUMeasurementDelegateImpl() final = default;
-
-  base::TimeDelta GetCumulativeCPUUsage() final;
-
- private:
-  std::unique_ptr<base::ProcessMetrics> process_metrics_;
-};
-
-CPUMeasurementDelegateImpl::CPUMeasurementDelegateImpl(
-    const ProcessNode* process_node) {
-  const base::ProcessHandle handle = process_node->GetProcess().Handle();
-#if BUILDFLAG(IS_MAC)
-  process_metrics_ = base::ProcessMetrics::CreateProcessMetrics(
-      handle, content::BrowserChildProcessHost::GetPortProvider());
-#else
-  process_metrics_ = base::ProcessMetrics::CreateProcessMetrics(handle);
-#endif
-}
-
-base::TimeDelta CPUMeasurementDelegateImpl::GetCumulativeCPUUsage() {
-#if BUILDFLAG(IS_WIN)
-  return process_metrics_->GetPreciseCumulativeCPUUsage();
-#else
-  return process_metrics_->GetCumulativeCPUUsage();
-#endif
-}
-
 // Returns true if `result` is in the default-initialized state.
 bool IsEmptyCPUTimeResult(const CPUTimeResult& result) {
   if (result.metadata.measurement_time.is_null()) {
@@ -145,11 +105,11 @@
   ValidateCPUTimeResult(result);
 }
 
-// Recursively visits all client workers of `worker_node`, and all client frames
-// of each worker, and adds each frame's PageNode to `client_pages`.
-// `visited_workers` is used to check for loops in the graph of client workers.
-// `graph_change` is a change to the graph topology in progress that may affect
-// the client page set, or NoGraphChange.
+// Recursively visits all client workers of `worker_node`, and all client
+// frames of each worker, and adds each frame's PageNode to `client_pages`.
+// `visited_workers` is used to check for loops in the graph of client
+// workers. `graph_change` is a change to the graph topology in progress that
+// may affect the client page set, or NoGraphChange.
 void RecursivelyFindClientPages(const WorkerNode* worker_node,
                                 GraphChange graph_change,
                                 std::set<const PageNode*>& client_pages,
@@ -212,7 +172,7 @@
 
 CPUMeasurementMonitor::CPUMeasurementMonitor()
     : cpu_measurement_delegate_factory_(
-          base::BindRepeating(&CPUMeasurementDelegateImpl::Create)) {}
+          CPUMeasurementDelegate::GetDefaultFactory()) {}
 
 CPUMeasurementMonitor::~CPUMeasurementMonitor() {
   if (graph_) {
@@ -222,16 +182,12 @@
 }
 
 void CPUMeasurementMonitor::SetCPUMeasurementDelegateFactoryForTesting(
-    CPUMeasurementDelegate::FactoryCallback factory) {
+    CPUMeasurementDelegate::Factory* factory) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   // Ensure that all CPU measurements use the same delegate.
   CHECK(cpu_measurement_map_.empty());
-  if (factory.is_null()) {
-    cpu_measurement_delegate_factory_ =
-        base::BindRepeating(&CPUMeasurementDelegateImpl::Create);
-  } else {
-    cpu_measurement_delegate_factory_ = std::move(factory);
-  }
+  CHECK(factory);
+  cpu_measurement_delegate_factory_ = factory;
 }
 
 void CPUMeasurementMonitor::StartMonitoring(Graph* graph) {
@@ -245,8 +201,8 @@
   // Start monitoring CPU usage for all existing processes. Can't read their CPU
   // usage until they have a pid assigned.
   graph_->VisitAllProcessNodes([this](const ProcessNode* process_node) {
-    if (process_node->GetProcessType() == content::PROCESS_TYPE_RENDERER &&
-        process_node->GetProcessId() != base::kNullProcessId) {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    if (cpu_measurement_delegate_factory_->ShouldMeasureProcess(process_node)) {
       MonitorCPUUsage(process_node);
     }
     return true;
@@ -310,19 +266,9 @@
     CHECK(cpu_measurement_map_.empty());
     return;
   }
-  // Only handle process start notifications (which is when the pid is
-  // assigned), not exit notifications. Note the pid can be reassigned if a
-  // process dies and a new one is started for the same ProcessNode - in that
-  // case MonitorCPUUsage will reset the measurements and start monitoring the
-  // new process from scratch.
-  if (!process_node->GetProcess().IsValid()) {
-    return;
+  if (cpu_measurement_delegate_factory_->ShouldMeasureProcess(process_node)) {
+    MonitorCPUUsage(process_node);
   }
-  CHECK_NE(process_node->GetProcessId(), base::kNullProcessId);
-  if (process_node->GetProcessType() != content::PROCESS_TYPE_RENDERER) {
-    return;
-  }
-  MonitorCPUUsage(process_node);
 }
 
 void CPUMeasurementMonitor::OnBeforeProcessNodeRemoved(
@@ -412,7 +358,9 @@
   // measurements in the same ProcessContext.
   cpu_measurement_map_.insert_or_assign(
       process_node,
-      CPUMeasurement(cpu_measurement_delegate_factory_.Run(process_node)));
+      CPUMeasurement(
+          cpu_measurement_delegate_factory_->CreateDelegateForProcess(
+              process_node)));
 }
 
 void CPUMeasurementMonitor::UpdateAllCPUMeasurements() {
diff --git a/components/performance_manager/resource_attribution/cpu_measurement_monitor.h b/components/performance_manager/resource_attribution/cpu_measurement_monitor.h
index 07c2b13a..4ec335f 100644
--- a/components/performance_manager/resource_attribution/cpu_measurement_monitor.h
+++ b/components/performance_manager/resource_attribution/cpu_measurement_monitor.h
@@ -43,10 +43,10 @@
   CPUMeasurementMonitor(const CPUMeasurementMonitor& other) = delete;
   CPUMeasurementMonitor& operator=(const CPUMeasurementMonitor&) = delete;
 
-  // The given `factory_callback` will be called to create a
-  // CPUMeasurementDelegate for each ProcessNode to be measured.
+  // The given `factory` will be used to create a CPUMeasurementDelegate for
+  // each ProcessNode to be measured.
   void SetCPUMeasurementDelegateFactoryForTesting(
-      CPUMeasurementDelegate::FactoryCallback factory_callback);
+      CPUMeasurementDelegate::Factory* factory);
 
   // Starts monitoring CPU usage for all renderer ProcessNode's in `graph`.
   void StartMonitoring(Graph* graph);
@@ -163,9 +163,9 @@
   std::map<ResourceContext, CPUTimeResult> measurement_results_
       GUARDED_BY_CONTEXT(sequence_checker_);
 
-  // Callback that will be invoked to create CPUMeasurementDelegate objects for
-  // each ProcessNode being measured.
-  CPUMeasurementDelegate::FactoryCallback cpu_measurement_delegate_factory_
+  // Factory that creates CPUMeasurementDelegate objects for each ProcessNode
+  // being measured.
+  raw_ptr<CPUMeasurementDelegate::Factory> cpu_measurement_delegate_factory_
       GUARDED_BY_CONTEXT(sequence_checker_);
 
   // Graph being monitored. This will be only be set if StartMonitoring() was
diff --git a/components/performance_manager/resource_attribution/cpu_measurement_monitor_unittest.cc b/components/performance_manager/resource_attribution/cpu_measurement_monitor_unittest.cc
index 07c466d..2199900 100644
--- a/components/performance_manager/resource_attribution/cpu_measurement_monitor_unittest.cc
+++ b/components/performance_manager/resource_attribution/cpu_measurement_monitor_unittest.cc
@@ -90,8 +90,10 @@
   void SetUp() override {
     GetGraphFeatures().EnableResourceAttributionScheduler();
     Super::SetUp();
-    cpu_monitor_.SetCPUMeasurementDelegateFactoryForTesting(
-        delegate_factory_.GetFactoryCallback());
+    // These tests validate specific timing of measurements around process
+    // creation and destruction.
+    delegate_factory_.SetRequireValidProcesses(true);
+    cpu_monitor_.SetCPUMeasurementDelegateFactoryForTesting(&delegate_factory_);
   }
 
   // Creates a renderer process and starts mocking its CPU measurements. By
diff --git a/components/performance_manager/resource_attribution/query_scheduler_unittest.cc b/components/performance_manager/resource_attribution/query_scheduler_unittest.cc
index 0f17240..7989689 100644
--- a/components/performance_manager/resource_attribution/query_scheduler_unittest.cc
+++ b/components/performance_manager/resource_attribution/query_scheduler_unittest.cc
@@ -48,6 +48,8 @@
   void SetUp() override {
     GetGraphFeatures().EnableResourceAttributionScheduler();
     Super::SetUp();
+    CPUMeasurementDelegate::SetDelegateFactoryForTesting(graph(),
+                                                         &delegate_factory_);
   }
 
   // This must be deleted after TearDown() so that it outlives the
@@ -57,9 +59,6 @@
 
 TEST_F(QuerySchedulerTest, CPUQueries) {
   MockSinglePageInSingleProcessGraph mock_graph(graph());
-  CPUMeasurementDelegate::SetDelegateFactoryForTesting(
-      graph(), delegate_factory_.GetFactoryCallback());
-  delegate_factory_.SetDefaultCPUUsage(99);
 
   auto* scheduler = QueryScheduler::GetFromGraph(graph());
   ASSERT_TRUE(scheduler);
@@ -89,9 +88,6 @@
 TEST_F(QuerySchedulerTest, GraphTeardown) {
   // Make sure queries that still exist when the scheduler is deleted during
   // graph teardown safely return no data.
-  CPUMeasurementDelegate::SetDelegateFactoryForTesting(
-      graph(), delegate_factory_.GetFactoryCallback());
-
   auto* scheduler = QueryScheduler::GetFromGraph(graph());
   ASSERT_TRUE(scheduler);
   auto weak_scheduler = scheduler->GetWeakPtr();
diff --git a/components/performance_manager/test_support/performance_manager_browsertest_harness.h b/components/performance_manager/test_support/performance_manager_browsertest_harness.h
index 46d7c437..e68c867 100644
--- a/components/performance_manager/test_support/performance_manager_browsertest_harness.h
+++ b/components/performance_manager/test_support/performance_manager_browsertest_harness.h
@@ -8,7 +8,7 @@
 #include <set>
 
 #include "base/memory/raw_ptr.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "components/performance_manager/embedder/graph_features.h"
 #include "content/public/test/content_browser_test.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/components/performance_manager/test_support/resource_attribution/simulated_cpu_measurement_delegate.cc b/components/performance_manager/test_support/resource_attribution/simulated_cpu_measurement_delegate.cc
index 5aba9b0..2872840f 100644
--- a/components/performance_manager/test_support/resource_attribution/simulated_cpu_measurement_delegate.cc
+++ b/components/performance_manager/test_support/resource_attribution/simulated_cpu_measurement_delegate.cc
@@ -11,6 +11,7 @@
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
 #include "components/performance_manager/public/graph/process_node.h"
+#include "content/public/common/process_type.h"
 
 namespace performance_manager::resource_attribution {
 
@@ -27,15 +28,13 @@
 }
 
 void SimulatedCPUMeasurementDelegateFactory::SetDefaultCPUUsage(
-    double default_cpu_usage) {
+    SimulatedCPUUsage default_cpu_usage) {
   default_cpu_usage_ = default_cpu_usage;
 }
 
-CPUMeasurementDelegate::FactoryCallback
-SimulatedCPUMeasurementDelegateFactory::GetFactoryCallback() {
-  return base::BindRepeating(
-      &SimulatedCPUMeasurementDelegateFactory::TakeDelegate,
-      weak_factory_.GetSafeRef());
+void SimulatedCPUMeasurementDelegateFactory::SetRequireValidProcesses(
+    bool require_valid) {
+  require_valid_processes_ = require_valid;
 }
 
 SimulatedCPUMeasurementDelegate&
@@ -47,12 +46,9 @@
     return *(it->second);
   }
   // Create a new delegate, saving it in `pending_cpu_delegates_` until someone
-  // calls TakeDelegate().
+  // calls CreateDelegateForProcess().
   auto new_delegate = std::make_unique<SimulatedCPUMeasurementDelegate>(
-      PassKey(), weak_factory_.GetSafeRef());
-  if (default_cpu_usage_) {
-    new_delegate->SetCPUUsage(default_cpu_usage_);
-  }
+      PassKey(), weak_factory_.GetSafeRef(), default_cpu_usage_);
   auto* delegate_ptr = new_delegate.get();
   simulated_cpu_delegates_.emplace(process_node, delegate_ptr);
   const auto [_, inserted] =
@@ -61,8 +57,19 @@
   return *delegate_ptr;
 }
 
+bool SimulatedCPUMeasurementDelegateFactory::ShouldMeasureProcess(
+    const ProcessNode* process_node) {
+  if (require_valid_processes_) {
+    // Delegate the decision to the production factory.
+    return CPUMeasurementDelegate::GetDefaultFactory()->ShouldMeasureProcess(
+        process_node);
+  }
+  // Measure only renderer processes, as in production.
+  return process_node->GetProcessType() == content::PROCESS_TYPE_RENDERER;
+}
+
 std::unique_ptr<CPUMeasurementDelegate>
-SimulatedCPUMeasurementDelegateFactory::TakeDelegate(
+SimulatedCPUMeasurementDelegateFactory::CreateDelegateForProcess(
     const ProcessNode* process_node) {
   // If there was a delegate already created, use it.
   auto it = pending_cpu_delegates_.find(process_node);
@@ -74,10 +81,7 @@
   }
   // Create a new delegate.
   auto new_delegate = std::make_unique<SimulatedCPUMeasurementDelegate>(
-      PassKey(), weak_factory_.GetSafeRef());
-  if (default_cpu_usage_) {
-    new_delegate->SetCPUUsage(default_cpu_usage_);
-  }
+      PassKey(), weak_factory_.GetSafeRef(), default_cpu_usage_);
   auto* delegate_ptr = new_delegate.get();
   simulated_cpu_delegates_.emplace(process_node, delegate_ptr);
   return new_delegate;
@@ -94,14 +98,17 @@
 
 SimulatedCPUMeasurementDelegate::SimulatedCPUMeasurementDelegate(
     base::PassKey<SimulatedCPUMeasurementDelegateFactory>,
-    base::SafeRef<SimulatedCPUMeasurementDelegateFactory> factory)
-    : factory_(factory) {}
+    base::SafeRef<SimulatedCPUMeasurementDelegateFactory> factory,
+    SimulatedCPUUsage initial_usage)
+    : factory_(factory) {
+  SetCPUUsage(initial_usage);
+}
 
 SimulatedCPUMeasurementDelegate::~SimulatedCPUMeasurementDelegate() {
   factory_->OnDelegateDeleted(PassKey(), this);
 }
 
-void SimulatedCPUMeasurementDelegate::SetCPUUsage(double usage,
+void SimulatedCPUMeasurementDelegate::SetCPUUsage(SimulatedCPUUsage usage,
                                                   base::TimeTicks start_time) {
   if (!cpu_usage_periods_.empty()) {
     cpu_usage_periods_.back().end_time = start_time;
diff --git a/components/performance_manager/test_support/resource_attribution/simulated_cpu_measurement_delegate.h b/components/performance_manager/test_support/resource_attribution/simulated_cpu_measurement_delegate.h
index de65ed1..68584824b 100644
--- a/components/performance_manager/test_support/resource_attribution/simulated_cpu_measurement_delegate.h
+++ b/components/performance_manager/test_support/resource_attribution/simulated_cpu_measurement_delegate.h
@@ -25,15 +25,30 @@
 
 class SimulatedCPUMeasurementDelegate;
 
+// The proportion of CPU used over time as a fraction, on the same scale as
+// ProcessMetrics::GetPlatformIndependentCPUUsage: 0% to 100% *
+// SysInfo::NumberOfProcessors().
+//
+// Since tests should be independent of the number of processors, it's usually
+// convenient to use a range of 0.0 to 1.0 (for 100%), simulating a
+// single-processor system. But if the code under test scales CPU measurements
+// by SysInfo::NumberOfProcessors(), it's better to set the simulated usage to
+// SysInfo::NumberOfProcessors() * a fraction, so that the code under test
+// gets the same results after scaling on every system.
+using SimulatedCPUUsage = double;
+
 // A factory that manages SimulatedCPUMeasurementDelegate instances. Embed an
-// instance of this in a unit test, and pass the result of GetFactoryCallback()
-// to CPUMeasurementDelegate::SetDelegateFactoryForTesting().
-class SimulatedCPUMeasurementDelegateFactory {
+// instance of this in a unit test, and pass it to
+// CPUMeasurementDelegate::SetDelegateFactoryForTesting(). The caller must
+// ensure that the SimulatedCPUMeasurementDelegateFactory outlives all callers
+// of CreateDelegateForProcess().
+class SimulatedCPUMeasurementDelegateFactory final
+    : public CPUMeasurementDelegate::Factory {
  public:
   using PassKey = base::PassKey<SimulatedCPUMeasurementDelegateFactory>;
 
   SimulatedCPUMeasurementDelegateFactory();
-  ~SimulatedCPUMeasurementDelegateFactory();
+  ~SimulatedCPUMeasurementDelegateFactory() final;
 
   SimulatedCPUMeasurementDelegateFactory(
       const SimulatedCPUMeasurementDelegateFactory&) = delete;
@@ -41,32 +56,42 @@
       const SimulatedCPUMeasurementDelegateFactory&) = delete;
 
   // Sets the default CPU usage reported by delegates created by this factory.
-  void SetDefaultCPUUsage(double default_cpu_usage);
+  // If this is not called, all delegates will report 100% CPU.
+  void SetDefaultCPUUsage(SimulatedCPUUsage default_cpu_usage);
 
-  // Returns a callback that can be passed to
-  // CPUMeasurementDelegate::SetDelegateFactoryForTesting to use
-  // SimulatedCPUMeasurementDelegates in tests. The caller must ensure that the
-  // SimulatedCPUMeasurementDelegateFactory outlives all users of the callback,
-  // otherwise it will crash when it's invoked.
-  CPUMeasurementDelegate::FactoryCallback GetFactoryCallback();
+  // By default, delegates created by this factory can return simulated
+  // measurements for ProcessNodes without a valid base::Process backing them.
+  // This is useful because most tests use shim ProcessNodes and only need the
+  // delegates to provide simple test data. Calling this with `require_valid`
+  // true will apply all the valid process checks used in production, for tests
+  // that do strict validation of CPU measurements.
+  void SetRequireValidProcesses(bool require_valid);
 
   // Returns a delegate for `process_node`. This can be used to set initial
   // values on delegates before the code under test gets a pointer to them using
-  // the factory callback returned from GetCallback().
+  // CreateDelegateForProcess().
   SimulatedCPUMeasurementDelegate& GetDelegate(const ProcessNode* process_node);
 
+  // CPUMeasurementDelegate::Factory implementation
+
+  bool ShouldMeasureProcess(const ProcessNode* process_node) final;
+
+  std::unique_ptr<CPUMeasurementDelegate> CreateDelegateForProcess(
+      const ProcessNode* process_node) final;
+
+  // Private implementation guarded by PassKey
+
   // Called by `delegate` when it's deleted.
   void OnDelegateDeleted(base::PassKey<SimulatedCPUMeasurementDelegate>,
                          SimulatedCPUMeasurementDelegate* delegate);
 
-  // Factory function for SimulatedCPUMeasurementDelegate objects. Passes
-  // ownership of the delegate for `process_node` to the caller, creating a
-  // delegate if none exists yet. Exposed through GetFactoryCallback().
-  std::unique_ptr<CPUMeasurementDelegate> TakeDelegate(
-      const ProcessNode* process_node);
-
+ private:
   // The default CPU usage of delegates created by this factory.
-  double default_cpu_usage_ = 0.0;
+  SimulatedCPUUsage default_cpu_usage_ = 1.0;
+
+  // If true, this factory won't create delegates for ProcessNodes without a
+  // valid base::Process.
+  bool require_valid_processes_ = false;
 
   // Map of ProcessNode to CPUMeasurementDelegate that simulates that process.
   // The delegates are owned by `pending_cpu_delegates_` when they're created,
@@ -91,7 +116,8 @@
   // Only SimulatedCPUMeasurementDelegateFactory can call the constructor.
   SimulatedCPUMeasurementDelegate(
       base::PassKey<SimulatedCPUMeasurementDelegateFactory>,
-      base::SafeRef<SimulatedCPUMeasurementDelegateFactory> factory);
+      base::SafeRef<SimulatedCPUMeasurementDelegateFactory> factory,
+      SimulatedCPUUsage initial_usage);
 
   ~SimulatedCPUMeasurementDelegate() final;
 
@@ -102,7 +128,7 @@
 
   // Sets the CPU usage to `usage`, starting at `start_time` (which must be
   // later than any `start_time` previously used).
-  void SetCPUUsage(double usage,
+  void SetCPUUsage(SimulatedCPUUsage usage,
                    base::TimeTicks start_time = base::TimeTicks::Now());
 
   // Sets the process to have an error that will be reported as `usage_error`.
@@ -121,7 +147,7 @@
   struct CPUUsagePeriod {
     base::TimeTicks start_time;
     base::TimeTicks end_time;
-    double cpu_usage;
+    SimulatedCPUUsage cpu_usage;
   };
 
   // The factory that created this delegate. The factory's destructor CHECK's
diff --git a/components/policy/content/safe_sites_navigation_throttle.h b/components/policy/content/safe_sites_navigation_throttle.h
index e43ec1a..a7bcca6e 100644
--- a/components/policy/content/safe_sites_navigation_throttle.h
+++ b/components/policy/content/safe_sites_navigation_throttle.h
@@ -8,7 +8,7 @@
 #include "base/functional/callback_forward.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "content/public/browser/navigation_throttle.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
diff --git a/components/policy/core/common/cloud/cloud_policy_client.h b/components/policy/core/common/cloud/cloud_policy_client.h
index e4bba267..2e196f7f 100644
--- a/components/policy/core/common/cloud/cloud_policy_client.h
+++ b/components/policy/core/common/cloud/cloud_policy_client.h
@@ -19,7 +19,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/observer_list.h"
 #include "base/sequence_checker.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "base/values.h"
 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
diff --git a/components/policy/resources/templates/policy_definitions/Attestation/AttestationEnabledForDevice.yaml b/components/policy/resources/templates/policy_definitions/Attestation/AttestationEnabledForDevice.yaml
index c3b3fed2..3e993dd 100644
--- a/components/policy/resources/templates/policy_definitions/Attestation/AttestationEnabledForDevice.yaml
+++ b/components/policy/resources/templates/policy_definitions/Attestation/AttestationEnabledForDevice.yaml
@@ -1,7 +1,9 @@
-# TODO(b/285556135): Remove or deprecate this policy
 caption: Enable remote attestation for the device
+deprecated: true
 default: false
 desc: |-
+  This policy was removed in M121. It served to enable and disable Remote Attestation for the device but Remote Attestation has been enabled by default.
+
   Setting the policy to Enabled allows remote attestation for the device. A certificate is automatically generated and uploaded to the Device Management Server.
 
   Setting the policy to Disabled or leaving it unset means no certificate is generated and calls to the <ph name="ENTERPRISE_PLATFORM_KEYS_API">Enterprise Platform Keys API</ph> fail.
@@ -22,6 +24,6 @@
 supported_chrome_os_management:
 - google_cloud
 supported_on:
-- chrome_os:28-
+- chrome_os:28-120
 tags: []
 type: main
diff --git a/components/reporting/client/report_queue_factory.h b/components/reporting/client/report_queue_factory.h
index 5616708..349df58ff 100644
--- a/components/reporting/client/report_queue_factory.h
+++ b/components/reporting/client/report_queue_factory.h
@@ -8,7 +8,7 @@
 #include <memory>
 
 #include "base/functional/callback.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/task/sequenced_task_runner.h"
 #include "components/reporting/client/report_queue.h"
 #include "components/reporting/client/report_queue_configuration.h"
diff --git a/components/reporting/metrics/metric_report_queue_unittest.cc b/components/reporting/metrics/metric_report_queue_unittest.cc
index 73da00a..4e2f485 100644
--- a/components/reporting/metrics/metric_report_queue_unittest.cc
+++ b/components/reporting/metrics/metric_report_queue_unittest.cc
@@ -7,7 +7,7 @@
 #include <memory>
 #include <string>
 
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/task/thread_pool.h"
 #include "base/test/bind.h"
diff --git a/components/reporting/util/status.h b/components/reporting/util/status.h
index 62b506c..2b1bee2 100644
--- a/components/reporting/util/status.h
+++ b/components/reporting/util/status.h
@@ -9,6 +9,7 @@
 #include <iosfwd>
 #include <string>
 
+#include "base/check.h"
 #include "base/strings/string_piece.h"
 #include "components/reporting/proto/synced/status.pb.h"
 
diff --git a/components/segmentation_platform/embedder/default_model/database_api_clients.h b/components/segmentation_platform/embedder/default_model/database_api_clients.h
index aa8d75e..75e0795d 100644
--- a/components/segmentation_platform/embedder/default_model/database_api_clients.h
+++ b/components/segmentation_platform/embedder/default_model/database_api_clients.h
@@ -7,7 +7,7 @@
 
 #include <memory>
 
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "components/segmentation_platform/internal/metadata/metadata_writer.h"
 #include "components/segmentation_platform/public/config.h"
 #include "components/segmentation_platform/public/model_provider.h"
diff --git a/components/segmentation_platform/embedder/default_model/device_switcher_result_dispatcher_unittest.cc b/components/segmentation_platform/embedder/default_model/device_switcher_result_dispatcher_unittest.cc
index ca91115..98288ff 100644
--- a/components/segmentation_platform/embedder/default_model/device_switcher_result_dispatcher_unittest.cc
+++ b/components/segmentation_platform/embedder/default_model/device_switcher_result_dispatcher_unittest.cc
@@ -6,7 +6,7 @@
 #include <memory>
 
 #include "base/run_loop.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/test/gmock_callback_support.h"
 #include "base/test/gmock_move_support.h"
 #include "base/test/task_environment.h"
diff --git a/components/segmentation_platform/embedder/input_delegate/tab_rank_dispatcher.h b/components/segmentation_platform/embedder/input_delegate/tab_rank_dispatcher.h
index bea7209..dabc701 100644
--- a/components/segmentation_platform/embedder/input_delegate/tab_rank_dispatcher.h
+++ b/components/segmentation_platform/embedder/input_delegate/tab_rank_dispatcher.h
@@ -11,7 +11,7 @@
 #include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/supports_user_data.h"
 #include "base/time/time.h"
 #include "components/segmentation_platform/embedder/tab_fetcher.h"
diff --git a/components/segmentation_platform/internal/selection/segment_selector_unittest.cc b/components/segmentation_platform/internal/selection/segment_selector_unittest.cc
index b9beb4d..d2a0204 100644
--- a/components/segmentation_platform/internal/selection/segment_selector_unittest.cc
+++ b/components/segmentation_platform/internal/selection/segment_selector_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 "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "components/segmentation_platform/internal/execution/model_execution_status.h"
 #include "components/segmentation_platform/internal/selection/segment_selector_impl.h"
 
diff --git a/components/segmentation_platform/public/database_client.h b/components/segmentation_platform/public/database_client.h
index 3b96a54..f0f4ac9 100644
--- a/components/segmentation_platform/public/database_client.h
+++ b/components/segmentation_platform/public/database_client.h
@@ -8,7 +8,7 @@
 #include <cstdint>
 
 #include "base/functional/callback_forward.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "base/types/id_type.h"
 #include "components/segmentation_platform/public/model_provider.h"
diff --git a/components/services/storage/indexed_db/scopes/varint_coding_unittest.cc b/components/services/storage/indexed_db/scopes/varint_coding_unittest.cc
index 034abd7..93933f08 100644
--- a/components/services/storage/indexed_db/scopes/varint_coding_unittest.cc
+++ b/components/services/storage/indexed_db/scopes/varint_coding_unittest.cc
@@ -3,6 +3,8 @@
 // found in the LICENSE file.
 
 #include "components/services/storage/indexed_db/scopes/varint_coding.h"
+
+#include "base/dcheck_is_on.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace content {
diff --git a/components/signin/internal/identity_manager/primary_account_manager.cc b/components/signin/internal/identity_manager/primary_account_manager.cc
index ffae63d..bc448cf 100644
--- a/components/signin/internal/identity_manager/primary_account_manager.cc
+++ b/components/signin/internal/identity_manager/primary_account_manager.cc
@@ -134,16 +134,18 @@
   }
 
   void SetBoolean(const std::string& path, bool value) {
-    if (pref_service_->GetBoolean(path) == value)
+    if (pref_service_->GetBoolean(path) == value) {
       return;
+    }
 
     need_commit_ = true;
     pref_service_->SetBoolean(path, value);
   }
 
   void SetString(const std::string& path, const std::string& value) {
-    if (pref_service_->GetString(path) == value)
+    if (pref_service_->GetString(path) == value) {
       return;
+    }
 
     need_commit_ = true;
     pref_service_->SetString(path, value);
@@ -644,8 +646,11 @@
 
   LogPrimaryAccountChangeMetrics(event_details, event_source);
 
-  for (Observer& observer : observers_)
+  client_->OnPrimaryAccountChangedWithEventSource(event_details, event_source);
+
+  for (Observer& observer : observers_) {
     observer.OnPrimaryAccountChanged(event_details);
+  }
 }
 
 void PrimaryAccountManager::OnRefreshTokensLoaded() {
diff --git a/components/signin/internal/identity_manager/token_binding_helper.h b/components/signin/internal/identity_manager/token_binding_helper.h
index 25e2f5a..59ad3b9 100644
--- a/components/signin/internal/identity_manager/token_binding_helper.h
+++ b/components/signin/internal/identity_manager/token_binding_helper.h
@@ -9,7 +9,7 @@
 #include "base/containers/span.h"
 #include "base/functional/callback_forward.h"
 #include "base/memory/raw_ref.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "components/unexportable_keys/service_error.h"
 #include "components/unexportable_keys/unexportable_key_id.h"
 
diff --git a/components/signin/public/base/BUILD.gn b/components/signin/public/base/BUILD.gn
index dbe38992..998f0728 100644
--- a/components/signin/public/base/BUILD.gn
+++ b/components/signin/public/base/BUILD.gn
@@ -101,6 +101,9 @@
     "//base/test:test_support",
     "//build:chromeos_buildflags",
     "//components/prefs",
+
+    # TODO(b/309104936): Remove this unwanted dependency.
+    "//components/signin/public/identity_manager:identity_manager",
     "//crypto",
     "//google_apis:test_support",
   ]
diff --git a/components/signin/public/base/DEPS b/components/signin/public/base/DEPS
index e603ed21..d660244 100644
--- a/components/signin/public/base/DEPS
+++ b/components/signin/public/base/DEPS
@@ -3,4 +3,6 @@
   "+third_party/re2/src/re2/re2.h",
   "+components/account_manager_core/account.h",
   "+components/signin/public/android/jni_headers/SigninFeatureMap_jni.h",
+  #TODO(b/309104936): Remove this unwanted include rule.
+  "+components/signin/public/identity_manager/primary_account_change_event.h",
 ]
diff --git a/components/signin/public/base/session_binding_utils.h b/components/signin/public/base/session_binding_utils.h
index ae24d70..31e7e2be 100644
--- a/components/signin/public/base/session_binding_utils.h
+++ b/components/signin/public/base/session_binding_utils.h
@@ -8,7 +8,7 @@
 #include <string>
 
 #include "base/containers/span.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "crypto/signature_verifier.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
diff --git a/components/signin/public/base/signin_client.h b/components/signin/public/base/signin_client.h
index cb06895..398b2a1 100644
--- a/components/signin/public/base/signin_client.h
+++ b/components/signin/public/base/signin_client.h
@@ -18,6 +18,7 @@
 #include "components/signin/public/base/signin_metrics.h"
 #include "google_apis/gaia/core_account_id.h"
 #include "google_apis/gaia/gaia_auth_fetcher.h"
+#include "third_party/abseil-cpp/absl/types/variant.h"
 #include "url/gurl.h"
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
@@ -43,6 +44,10 @@
 enum class Channel;
 }
 
+namespace signin {
+class PrimaryAccountChangeEvent;
+}
+
 // An interface that needs to be supplied to the Signin component by its
 // embedder.
 class SigninClient : public KeyedService {
@@ -139,6 +144,14 @@
   // Returns the channel for the client installation.
   virtual version_info::Channel GetClientChannel() = 0;
 
+  // Called when the primary account is changed, with additional information.
+  // `event_details` contains information on how the account changed.
+  // `event_source` contains information on how the signin/signout happened.
+  virtual void OnPrimaryAccountChangedWithEventSource(
+      signin::PrimaryAccountChangeEvent event_details,
+      absl::variant<signin_metrics::AccessPoint, signin_metrics::ProfileSignout>
+          event_source) = 0;
+
  protected:
   absl::optional<SignoutDecision> is_clear_primary_account_allowed_for_testing_;
 };
diff --git a/components/signin/public/base/test_signin_client.cc b/components/signin/public/base/test_signin_client.cc
index 8c2674e..df9b5dd4 100644
--- a/components/signin/public/base/test_signin_client.cc
+++ b/components/signin/public/base/test_signin_client.cc
@@ -9,6 +9,7 @@
 
 #include "base/check.h"
 #include "base/functional/callback.h"
+#include "components/signin/public/identity_manager/primary_account_change_event.h"
 #include "components/version_info/channel.h"
 #include "google_apis/gaia/gaia_auth_util.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -132,6 +133,11 @@
   return version_info::Channel::UNKNOWN;
 }
 
+void TestSigninClient::OnPrimaryAccountChangedWithEventSource(
+    signin::PrimaryAccountChangeEvent event_details,
+    absl::variant<signin_metrics::AccessPoint, signin_metrics::ProfileSignout>
+        event_source) {}
+
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
 absl::optional<account_manager::Account>
 TestSigninClient::GetInitialPrimaryAccount() {
diff --git a/components/signin/public/base/test_signin_client.h b/components/signin/public/base/test_signin_client.h
index 9ca18cf..64cc0b8 100644
--- a/components/signin/public/base/test_signin_client.h
+++ b/components/signin/public/base/test_signin_client.h
@@ -111,6 +111,10 @@
       GaiaAuthConsumer* consumer,
       gaia::GaiaSource source) override;
   version_info::Channel GetClientChannel() override;
+  void OnPrimaryAccountChangedWithEventSource(
+      signin::PrimaryAccountChangeEvent event_details,
+      absl::variant<signin_metrics::AccessPoint, signin_metrics::ProfileSignout>
+          event_source) override;
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
   absl::optional<account_manager::Account> GetInitialPrimaryAccount() override;
diff --git a/components/signin/public/identity_manager/identity_test_utils.h b/components/signin/public/identity_manager/identity_test_utils.h
index 187a81a8..d6c6276 100644
--- a/components/signin/public/identity_manager/identity_test_utils.h
+++ b/components/signin/public/identity_manager/identity_test_utils.h
@@ -8,7 +8,7 @@
 #include <string>
 
 #include "base/functional/callback_forward.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "build/build_config.h"
 #include "components/signin/public/base/consent_level.h"
diff --git a/components/supervised_user/core/browser/child_account_service.cc b/components/supervised_user/core/browser/child_account_service.cc
index fbc8822..44138dc3 100644
--- a/components/supervised_user/core/browser/child_account_service.cc
+++ b/components/supervised_user/core/browser/child_account_service.cc
@@ -13,7 +13,7 @@
 #include "base/functional/callback.h"
 #include "base/metrics/field_trial.h"
 #include "base/no_destructor.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/values.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
@@ -72,7 +72,7 @@
   identity_manager_->AddObserver(this);
 
   std::move(check_user_child_status_callback_)
-      .Run(supervised_user_service_->IsSubjectToParentalControls());
+      .Run(supervised_user::IsChildAccount(user_prefs_.get()));
 
   // If we're already signed in, check the account immediately just to be sure.
   // (We might have missed an update before registering as an observer.)
@@ -127,7 +127,7 @@
 }
 
 void ChildAccountService::SetActive(bool active) {
-  if (!supervised_user_service_->IsSubjectToParentalControls() && !active_) {
+  if (!supervised_user::IsChildAccount(user_prefs_.get()) && !active_) {
     return;
   }
   if (active_ == active) {
@@ -149,7 +149,7 @@
 
 void ChildAccountService::SetSupervisionStatusAndNotifyObservers(
     bool supervision_status) {
-  if (supervised_user_service_->IsSubjectToParentalControls() !=
+  if (supervised_user::IsChildAccount(user_prefs_.get()) !=
       supervision_status) {
     if (supervision_status) {
       EnableParentalControls(user_prefs_.get());
diff --git a/components/supervised_user/core/browser/supervised_user_preferences.cc b/components/supervised_user/core/browser/supervised_user_preferences.cc
index 3719fc9..b5070406 100644
--- a/components/supervised_user/core/browser/supervised_user_preferences.cc
+++ b/components/supervised_user/core/browser/supervised_user_preferences.cc
@@ -170,6 +170,10 @@
   return pref_service.GetBoolean(prefs::kChildAccountStatusKnown);
 }
 
+bool IsChildAccount(const PrefService& pref_service) {
+  return pref_service.GetString(prefs::kSupervisedUserId) == kChildAccountSUID;
+}
+
 }  // namespace supervised_user
 
 #if BUILDFLAG(IS_ANDROID)
diff --git a/components/supervised_user/core/browser/supervised_user_preferences.h b/components/supervised_user/core/browser/supervised_user_preferences.h
index bd95e84..b89c486 100644
--- a/components/supervised_user/core/browser/supervised_user_preferences.h
+++ b/components/supervised_user/core/browser/supervised_user_preferences.h
@@ -26,6 +26,11 @@
 
 bool IsChildAccountStatusKnown(PrefService& pref_service);
 
+// Returns true if the user is a type of Family Link supervised account.
+// This method should be preferred on gating child-specific features if there
+// is no dedicated method for the feature (e.g IsURLFilteringEnabled).
+bool IsChildAccount(const PrefService& pref_service);
+
 }  // namespace supervised_user
 
 #endif  // COMPONENTS_SUPERVISED_USER_CORE_BROWSER_SUPERVISED_USER_PREFERENCES_H_
diff --git a/components/supervised_user/core/browser/supervised_user_preferences_unittest.cc b/components/supervised_user/core/browser/supervised_user_preferences_unittest.cc
index 0e29d80..b04578f 100644
--- a/components/supervised_user/core/browser/supervised_user_preferences_unittest.cc
+++ b/components/supervised_user/core/browser/supervised_user_preferences_unittest.cc
@@ -36,6 +36,7 @@
       pref_service_.GetInteger(prefs::kDefaultSupervisedUserFilteringBehavior),
       static_cast<int>(supervised_user::FilteringBehavior::kAllow));
   EXPECT_EQ(pref_service_.GetBoolean(prefs::kSupervisedUserSafeSites), true);
+  EXPECT_FALSE(supervised_user::IsChildAccount(pref_service_));
   // TODO(b/306376651): When we migrate more preference reading methods in this
   // library, add more test cases for their correct default values.
 }
@@ -106,5 +107,16 @@
   }
 }
 
+TEST_F(SupervisedUserPreferencesTest, IsChildAccountSupervisedUser) {
+  pref_service_.SetString(prefs::kSupervisedUserId,
+                            supervised_user::kChildAccountSUID);
+  EXPECT_TRUE(supervised_user::IsChildAccount(pref_service_));
+}
+
+TEST_F(SupervisedUserPreferencesTest, IsChildAccountNonSupervisedUser) {
+  pref_service_.SetString(prefs::kSupervisedUserId, std::string());
+  EXPECT_FALSE(supervised_user::IsChildAccount(pref_service_));
+}
+
 }  // 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 4027d69..541a6f5 100644
--- a/components/supervised_user/core/browser/supervised_user_service.cc
+++ b/components/supervised_user/core/browser/supervised_user_service.cc
@@ -22,6 +22,7 @@
 #include "components/prefs/pref_service.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "components/supervised_user/core/browser/kids_chrome_management_client.h"
+#include "components/supervised_user/core/browser/supervised_user_preferences.h"
 #include "components/supervised_user/core/browser/supervised_user_service_observer.h"
 #include "components/supervised_user/core/browser/supervised_user_settings_service.h"
 #include "components/supervised_user/core/browser/supervised_user_url_filter.h"
@@ -59,7 +60,7 @@
 
   user_prefs_->SetInteger(prefs::kFirstTimeInterstitialBannerState,
                           static_cast<int>(banner_state));
-  SetActive(IsSubjectToParentalControls());
+  SetActive(supervised_user::IsChildAccount(user_prefs_.get()));
 }
 
 void SupervisedUserService::SetDelegate(Delegate* delegate) {
@@ -123,9 +124,9 @@
 
 bool SupervisedUserService::IsURLFilteringEnabled() const {
 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS)
-  return IsSubjectToParentalControls();
+  return supervised_user::IsChildAccount(user_prefs_.get());
 #else
-  return IsSubjectToParentalControls() &&
+  return supervised_user::IsChildAccount(user_prefs_.get()) &&
          base::FeatureList::IsEnabled(
              kFilterWebsitesForSupervisedUsersOnDesktopAndIOS);
 #endif
@@ -134,9 +135,9 @@
 bool SupervisedUserService::AreExtensionsPermissionsEnabled() const {
 #if BUILDFLAG(ENABLE_EXTENSIONS)
 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS)
-  return IsSubjectToParentalControls();
+  return supervised_user::IsChildAccount(user_prefs_.get());
 #else
-  return IsSubjectToParentalControls() &&
+  return supervised_user::IsChildAccount(user_prefs_.get()) &&
          base::FeatureList::IsEnabled(
              kEnableExtensionsPermissionsForSupervisedUsersOnDesktop);
 #endif
@@ -276,10 +277,6 @@
   }
 }
 
-bool SupervisedUserService::IsSubjectToParentalControls() const {
-  return user_prefs_->GetString(prefs::kSupervisedUserId) == kChildAccountSUID;
-}
-
 void SupervisedUserService::OnCustodianInfoChanged() {
   for (SupervisedUserServiceObserver& observer : observer_list_) {
     observer.OnCustodianInfoChanged();
@@ -287,7 +284,7 @@
 }
 
 void SupervisedUserService::OnSupervisedUserIdChanged() {
-  SetActive(IsSubjectToParentalControls());
+  SetActive(supervised_user::IsChildAccount(user_prefs_.get()));
 }
 
 void SupervisedUserService::OnDefaultFilteringBehaviorChanged() {
@@ -312,7 +309,7 @@
 }
 
 bool SupervisedUserService::IsSafeSitesEnabled() const {
-  return IsSubjectToParentalControls() &&
+  return supervised_user::IsChildAccount(user_prefs_.get()) &&
          user_prefs_->GetBoolean(prefs::kSupervisedUserSafeSites);
 }
 
@@ -391,7 +388,7 @@
   }
   DCHECK(!did_shutdown_);
   did_shutdown_ = true;
-  if (IsSubjectToParentalControls()) {
+  if (supervised_user::IsChildAccount(user_prefs_.get())) {
     base::RecordAction(UserMetricsAction("ManagedUsers_QuitBrowser"));
   }
   SetActive(false);
@@ -426,7 +423,7 @@
     return false;
   }
 
-  if (!IsSubjectToParentalControls()) {
+  if (!supervised_user::IsChildAccount(user_prefs_.get())) {
     return false;
   }
   return google_util::IsYoutubeDomainUrl(origin, google_util::ALLOW_SUBDOMAIN,
diff --git a/components/supervised_user/core/browser/supervised_user_service.h b/components/supervised_user/core/browser/supervised_user_service.h
index 443c63ac..54869e1 100644
--- a/components/supervised_user/core/browser/supervised_user_service.h
+++ b/components/supervised_user/core/browser/supervised_user_service.h
@@ -127,12 +127,6 @@
   }
 #endif  // BUILDFLAG(IS_CHROMEOS)
 
-  // Returns true if both: the user is a type of Family Link supervised account
-  // and the platform supports Family Link supervision features.
-  // This method should be prefered on gating child-specific features if there
-  // is no dedicated method for the feature (e.g IsURLFilteringEnabled).
-  virtual bool IsSubjectToParentalControls() const;
-
   // Updates the kFirstTimeInterstitialBannerState pref to indicate that the
   // user has been shown the interstitial banner. This will only update users
   // who haven't yet seen the banner.
diff --git a/components/supervised_user/core/browser/supervised_user_settings_service.h b/components/supervised_user/core/browser/supervised_user_settings_service.h
index 59082ce..dd7773f 100644
--- a/components/supervised_user/core/browser/supervised_user_settings_service.h
+++ b/components/supervised_user/core/browser/supervised_user_settings_service.h
@@ -12,7 +12,7 @@
 #include "base/callback_list.h"
 #include "base/functional/callback.h"
 #include "base/memory/ref_counted.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/values.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/prefs/pref_store.h"
diff --git a/components/supervised_user/test_support/kids_management_api_server_mock.cc b/components/supervised_user/test_support/kids_management_api_server_mock.cc
index a01c4db..6273732 100644
--- a/components/supervised_user/test_support/kids_management_api_server_mock.cc
+++ b/components/supervised_user/test_support/kids_management_api_server_mock.cc
@@ -8,7 +8,7 @@
 
 #include "base/functional/bind.h"
 #include "base/strings/strcat.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/test/scoped_feature_list.h"
 #include "components/supervised_user/core/browser/fetcher_config.h"
 #include "components/supervised_user/core/browser/proto/kidschromemanagement_messages.pb.h"
diff --git a/components/supervised_user/test_support/kids_management_api_server_mock.h b/components/supervised_user/test_support/kids_management_api_server_mock.h
index b116188..86585c8 100644
--- a/components/supervised_user/test_support/kids_management_api_server_mock.h
+++ b/components/supervised_user/test_support/kids_management_api_server_mock.h
@@ -11,7 +11,7 @@
 #include "base/callback_list.h"
 #include "base/functional/callback_forward.h"
 #include "base/memory/raw_ptr.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/test/scoped_feature_list.h"
 #include "components/supervised_user/core/browser/fetcher_config.h"
 #include "components/supervised_user/core/browser/proto/kidschromemanagement_messages.pb.h"
diff --git a/components/translate/core/browser/translate_browser_metrics.cc b/components/translate/core/browser/translate_browser_metrics.cc
index bc54185..c2dc640 100644
--- a/components/translate/core/browser/translate_browser_metrics.cc
+++ b/components/translate/core/browser/translate_browser_metrics.cc
@@ -5,9 +5,6 @@
 #include "components/translate/core/browser/translate_browser_metrics.h"
 
 #include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/metrics/metrics_hashes.h"
-#include "components/language/core/browser/language_usage_metrics.h"
 
 namespace translate {
 
@@ -17,8 +14,6 @@
 // a corresponding index in MetricsNameIndex and an entry in |kMetricsEntries|.
 const char kTranslateLanguageDetectionContentLength[] =
     "Translate.LanguageDetection.ContentLength";
-const char kTranslateUnsupportedLanguageAtInitiation[] =
-    "Translate.UnsupportedLanguageAtInitiation";
 const char kTranslateHrefHintStatus[] = "Translate.HrefHint.Status";
 const char kTranslateMenuTranslationUnavailableReasons[] =
     "Translate.MenuTranslation.UnavailableReasons";
@@ -29,8 +24,8 @@
 
 void ReportMenuTranslationUnavailableReason(
     MenuTranslationUnavailableReason reason) {
-  UMA_HISTOGRAM_ENUMERATION(kTranslateMenuTranslationUnavailableReasons,
-                            reason);
+  base::UmaHistogramEnumeration(kTranslateMenuTranslationUnavailableReasons,
+                                reason);
 }
 
 void ReportLanguageDetectionContentLength(size_t length) {
@@ -38,13 +33,6 @@
                                  length);
 }
 
-void ReportUnsupportedLanguageAtInitiation(base::StringPiece language) {
-  int language_code =
-      language::LanguageUsageMetrics::ToLanguageCodeHash(language);
-  base::UmaHistogramSparse(kTranslateUnsupportedLanguageAtInitiation,
-                           language_code);
-}
-
 void ReportTranslateHrefHintStatus(HrefTranslateStatus status) {
   base::UmaHistogramEnumeration(kTranslateHrefHintStatus, status);
 }
diff --git a/components/translate/core/browser/translate_browser_metrics.h b/components/translate/core/browser/translate_browser_metrics.h
index a152223..0d1e429 100644
--- a/components/translate/core/browser/translate_browser_metrics.h
+++ b/components/translate/core/browser/translate_browser_metrics.h
@@ -62,8 +62,6 @@
 // Called when language detection details are complete.
 void ReportLanguageDetectionContentLength(size_t length);
 
-void ReportUnsupportedLanguageAtInitiation(base::StringPiece language);
-
 // Called when a request is sent to the translate server to report the source
 // language of the translated page. Buckets are labelled with LocaleCodeISO639
 // values.
diff --git a/components/translate/core/browser/translate_browser_metrics_unittest.cc b/components/translate/core/browser/translate_browser_metrics_unittest.cc
index fae1eef..ad5abb1d 100644
--- a/components/translate/core/browser/translate_browser_metrics_unittest.cc
+++ b/components/translate/core/browser/translate_browser_metrics_unittest.cc
@@ -174,15 +174,6 @@
   recorder.CheckMenuTranslationUnavailableReason(1, 1, 1, 1, 1, 1, 1, 1);
 }
 
-TEST(TranslateBrowserMetricsTest, ReportedUnsupportedLanguageAtInitiation) {
-  const int ENGLISH = 25966;
-
-  MetricsRecorder recorder("Translate.UnsupportedLanguageAtInitiation");
-  EXPECT_EQ(0, recorder.GetTotalCount());
-  TranslateBrowserMetrics::ReportUnsupportedLanguageAtInitiation("en");
-  EXPECT_EQ(1, recorder.GetCount(ENGLISH));
-}
-
 TEST(TranslateBrowserMetricsTest, ReportTranslateHrefHintStatus) {
   MetricsRecorder recorder("Translate.HrefHint.Status");
   recorder.CheckTranslateHrefHintStatus(0, 0, 0, 0);
diff --git a/components/trusted_vault/features.cc b/components/trusted_vault/features.cc
index 775a754a..9d838665 100644
--- a/components/trusted_vault/features.cc
+++ b/components/trusted_vault/features.cc
@@ -30,11 +30,11 @@
 #if BUILDFLAG(IS_CHROMEOS)
 BASE_FEATURE(kChromeOSTrustedVaultUseWebUIDialog,
              "ChromeOSTrustedVaultUseWebUIDialog",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 BASE_FEATURE(kChromeOSTrustedVaultClientShared,
              "ChromeOSTrustedVaultClientShared",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 #endif
 
 }  // namespace trusted_vault
diff --git a/components/trusted_vault/trusted_vault_server_constants.h b/components/trusted_vault/trusted_vault_server_constants.h
index d2b27fb..df214f4 100644
--- a/components/trusted_vault/trusted_vault_server_constants.h
+++ b/components/trusted_vault/trusted_vault_server_constants.h
@@ -11,7 +11,7 @@
 
 #include "base/containers/fixed_flat_set.h"
 #include "base/containers/span.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
diff --git a/components/ui_devtools/devtools_server.h b/components/ui_devtools/devtools_server.h
index 994132de..110c3bb 100644
--- a/components/ui_devtools/devtools_server.h
+++ b/components/ui_devtools/devtools_server.h
@@ -10,7 +10,7 @@
 #include "base/compiler_specific.h"
 #include "base/functional/callback_forward.h"
 #include "base/memory/weak_ptr.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/threading/thread.h"
 #include "components/ui_devtools/devtools_client.h"
diff --git a/components/url_formatter/spoof_checks/idn_spoof_checker.h b/components/url_formatter/spoof_checks/idn_spoof_checker.h
index 9624578..4141d210 100644
--- a/components/url_formatter/spoof_checks/idn_spoof_checker.h
+++ b/components/url_formatter/spoof_checks/idn_spoof_checker.h
@@ -11,7 +11,7 @@
 #include "base/containers/flat_set.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "components/url_formatter/spoof_checks/idna_metrics.h"
 #include "components/url_formatter/spoof_checks/skeleton_generator.h"
 #include "net/extras/preload_data/decoder.h"
diff --git a/components/url_formatter/spoof_checks/skeleton_generator.h b/components/url_formatter/spoof_checks/skeleton_generator.h
index 16e6d1a5..a0c83121 100644
--- a/components/url_formatter/spoof_checks/skeleton_generator.h
+++ b/components/url_formatter/spoof_checks/skeleton_generator.h
@@ -11,7 +11,7 @@
 
 #include "base/containers/flat_set.h"
 #include "base/memory/raw_ptr.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 
 #include "third_party/icu/source/common/unicode/uniset.h"
 
diff --git a/components/url_pattern_index/url_pattern_index.h b/components/url_pattern_index/url_pattern_index.h
index 50527c8..326ff34 100644
--- a/components/url_pattern_index/url_pattern_index.h
+++ b/components/url_pattern_index/url_pattern_index.h
@@ -14,7 +14,7 @@
 #include "base/containers/flat_set.h"
 #include "base/functional/callback_forward.h"
 #include "base/memory/raw_ptr.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "components/url_pattern_index/closed_hash_map.h"
 #include "components/url_pattern_index/flat/url_pattern_index_generated.h"
 #include "components/url_pattern_index/proto/rules.pb.h"
diff --git a/components/user_education/common/feature_promo_lifecycle.h b/components/user_education/common/feature_promo_lifecycle.h
index 543a5d9..d3a2f67 100644
--- a/components/user_education/common/feature_promo_lifecycle.h
+++ b/components/user_education/common/feature_promo_lifecycle.h
@@ -8,7 +8,7 @@
 #include <memory>
 
 #include "base/memory/raw_ptr.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "components/feature_engagement/public/tracker.h"
 #include "components/user_education/common/feature_promo_result.h"
diff --git a/components/user_manager/known_user.cc b/components/user_manager/known_user.cc
index 0f227f32..388ddba 100644
--- a/components/user_manager/known_user.cc
+++ b/components/user_manager/known_user.cc
@@ -13,7 +13,7 @@
 #include "base/logging.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/notreached.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "base/values.h"
 #include "components/account_id/account_id.h"
diff --git a/components/user_manager/known_user.h b/components/user_manager/known_user.h
index 27a73f4..69ff30f 100644
--- a/components/user_manager/known_user.h
+++ b/components/user_manager/known_user.h
@@ -10,7 +10,7 @@
 
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "base/values.h"
 #include "base/version.h"
diff --git a/components/viz/service/frame_sinks/frame_counter.h b/components/viz/service/frame_sinks/frame_counter.h
index 76ca8e6..3486b716 100644
--- a/components/viz/service/frame_sinks/frame_counter.h
+++ b/components/viz/service/frame_sinks/frame_counter.h
@@ -6,7 +6,7 @@
 #define COMPONENTS_VIZ_SERVICE_FRAME_SINKS_FRAME_COUNTER_H_
 
 #include "base/containers/flat_map.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "components/viz/common/surfaces/frame_sink_id.h"
 #include "components/viz/service/viz_service_export.h"
diff --git a/components/web_package/input_reader.h b/components/web_package/input_reader.h
index 3a86446..48af887 100644
--- a/components/web_package/input_reader.h
+++ b/components/web_package/input_reader.h
@@ -7,7 +7,7 @@
 
 #include "base/big_endian.h"
 #include "base/containers/span.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace web_package {
diff --git a/components/web_package/signed_web_bundles/signed_web_bundle_id.h b/components/web_package/signed_web_bundles/signed_web_bundle_id.h
index c2b49364..d69ef33a 100644
--- a/components/web_package/signed_web_bundles/signed_web_bundle_id.h
+++ b/components/web_package/signed_web_bundles/signed_web_bundle_id.h
@@ -6,7 +6,7 @@
 #define COMPONENTS_WEB_PACKAGE_SIGNED_WEB_BUNDLES_SIGNED_WEB_BUNDLE_ID_H_
 
 #include "base/functional/callback.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/types/expected.h"
 #include "components/web_package/signed_web_bundles/ed25519_public_key.h"
 
diff --git a/components/webcrypto/algorithms/aes.h b/components/webcrypto/algorithms/aes.h
index 695afbc..b02f500 100644
--- a/components/webcrypto/algorithms/aes.h
+++ b/components/webcrypto/algorithms/aes.h
@@ -7,7 +7,7 @@
 
 #include <stdint.h>
 
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "components/webcrypto/algorithm_implementation.h"
 
 namespace webcrypto {
diff --git a/components/webcrypto/algorithms/secret_key_util.h b/components/webcrypto/algorithms/secret_key_util.h
index 8c5701a3..d4c29124 100644
--- a/components/webcrypto/algorithms/secret_key_util.h
+++ b/components/webcrypto/algorithms/secret_key_util.h
@@ -11,7 +11,7 @@
 #include <vector>
 
 #include "base/containers/span.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "third_party/blink/public/platform/web_crypto_algorithm.h"
 #include "third_party/blink/public/platform/web_crypto_key.h"
 
diff --git a/components/webcrypto/algorithms/test_helpers.h b/components/webcrypto/algorithms/test_helpers.h
index 622a45bd..44ba0289 100644
--- a/components/webcrypto/algorithms/test_helpers.h
+++ b/components/webcrypto/algorithms/test_helpers.h
@@ -13,7 +13,7 @@
 #include <vector>
 
 #include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/values.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/components/webcrypto/jwk.h b/components/webcrypto/jwk.h
index 814b324..6f5c044e 100644
--- a/components/webcrypto/jwk.h
+++ b/components/webcrypto/jwk.h
@@ -11,7 +11,7 @@
 #include <vector>
 
 #include "base/containers/span.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "base/values.h"
 #include "third_party/blink/public/platform/web_crypto.h"
 
diff --git a/components/webcrypto/status.h b/components/webcrypto/status.h
index db330c48..aeff312 100644
--- a/components/webcrypto/status.h
+++ b/components/webcrypto/status.h
@@ -9,7 +9,7 @@
 
 #include <string>
 
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "third_party/blink/public/platform/web_crypto.h"
 
 namespace webcrypto {
diff --git a/components/winhttp/network_fetcher.h b/components/winhttp/network_fetcher.h
index a1f2360..a9cf49c 100644
--- a/components/winhttp/network_fetcher.h
+++ b/components/winhttp/network_fetcher.h
@@ -20,7 +20,7 @@
 #include "base/memory/raw_ref.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/sequence_checker.h"
-#include "base/strings/string_piece_forward.h"
+#include "base/strings/string_piece.h"
 #include "components/winhttp/proxy_configuration.h"
 #include "components/winhttp/scoped_hinternet.h"
 #include "url/gurl.h"
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index d89bcc5..34e00e88 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -3327,8 +3327,6 @@
       "speech/speech_recognition_engine.h",
       "speech/speech_recognizer_impl.cc",
       "speech/speech_recognizer_impl.h",
-      "tracing/trace_report/trace_report_internals_ui.cc",
-      "tracing/trace_report/trace_report_internals_ui.h",
       "tracing/tracing_ui.cc",
       "tracing/tracing_ui.h",
 
@@ -3366,11 +3364,15 @@
     ]
   }
 
-  # Devtools frontend not included in Android and iOS
   if (!is_android && !is_ios) {
     sources += [
+      # Devtools frontend not included in Android and iOS
       "devtools/devtools_frontend_host_impl.cc",
       "devtools/devtools_frontend_host_impl.h",
+
+      # Trace report internal UI is not adapted for mobile use.
+      "tracing/trace_report/trace_report_internals_ui.cc",
+      "tracing/trace_report/trace_report_internals_ui.h",
     ]
 
     deps += [ "//content/browser/devtools:devtools_resources_extern" ]
diff --git a/content/browser/accessibility/dump_accessibility_node_browsertest.cc b/content/browser/accessibility/dump_accessibility_node_browsertest.cc
index d2594e7..a107ed6 100644
--- a/content/browser/accessibility/dump_accessibility_node_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_node_browsertest.cc
@@ -317,8 +317,16 @@
   RunAccNameTest(FILE_PATH_LITERAL("desc-combobox-focusable.html"));
 }
 
+// TODO(crbug.com/1500087): Re-enable this test
+#if BUILDFLAG(IS_MAC)
+#define MAYBE_DescFromContentOfDescribedbyElement \
+  DISABLED_DescFromContentOfDescribedbyElement
+#else
+#define MAYBE_DescFromContentOfDescribedbyElement \
+  DescFromContentOfDescribedbyElement
+#endif
 IN_PROC_BROWSER_TEST_P(DumpAccessibilityAccNameTest,
-                       DescFromContentOfDescribedbyElement) {
+                       MAYBE_DescFromContentOfDescribedbyElement) {
   RunAccNameTest(
       FILE_PATH_LITERAL("desc-from-content-of-describedby-element.html"));
 }
diff --git a/content/browser/back_forward_cache_features_browsertest.cc b/content/browser/back_forward_cache_features_browsertest.cc
index 56434fb..8cf8300 100644
--- a/content/browser/back_forward_cache_features_browsertest.cc
+++ b/content/browser/back_forward_cache_features_browsertest.cc
@@ -4789,8 +4789,9 @@
     : public BackForwardCacheBrowserTestWithMediaSession {
  public:
   void SetUpCommandLine(base::CommandLine* command_line) override {
-    BackForwardCacheBrowserTestWithMediaSession::SetUpCommandLine(command_line);
     command_line->AppendSwitch("disable-field-trial-config");
+    DisableFeature(features::kBackForwardCacheMediaSessionService);
+    BackForwardCacheBrowserTestWithMediaSession::SetUpCommandLine(command_line);
   }
 };
 
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc
index b615ebd..35cf0ef 100644
--- a/content/browser/browser_interface_binders.cc
+++ b/content/browser/browser_interface_binders.cc
@@ -1211,7 +1211,7 @@
                                          ProcessInternalsUI>(map);
   RegisterWebUIControllerInterfaceBinder<storage::mojom::QuotaInternalsHandler,
                                          QuotaInternalsUI>(map);
-#if !BUILDFLAG(IS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
   RegisterWebUIControllerInterfaceBinder<
       trace_report::mojom::TraceReportHandlerFactory, TraceReportInternalsUI>(
       map);
diff --git a/content/browser/devtools/protocol/storage_handler.cc b/content/browser/devtools/protocol/storage_handler.cc
index bc79258..351539a 100644
--- a/content/browser/devtools/protocol/storage_handler.cc
+++ b/content/browser/devtools/protocol/storage_handler.cc
@@ -1758,6 +1758,26 @@
       .Build();
 }
 
+std::unique_ptr<Array<Storage::AttributionReportingTriggerSpec>> ToTriggerSpecs(
+    const attribution_reporting::TriggerSpecs& specs) {
+  auto array =
+      std::make_unique<Array<Storage::AttributionReportingTriggerSpec>>();
+
+  for (const auto& spec : specs.specs()) {
+    array->emplace_back(Storage::AttributionReportingTriggerSpec::Create()
+                            .SetTriggerData(std::make_unique<Array<double>>())
+                            .SetEventReportWindows(ToEventReportWindows(
+                                spec.event_report_windows()))
+                            .Build());
+  }
+
+  for (const auto& [trigger_data, spec_index] : specs.trigger_data_indices()) {
+    array->at(spec_index)->GetTriggerData()->push_back(trigger_data);
+  }
+
+  return array;
+}
+
 Storage::AttributionReportingTriggerDataMatching ToTriggerDataMatching(
     attribution_reporting::mojom::TriggerDataMatching value) {
   switch (value) {
@@ -1799,8 +1819,12 @@
           .SetAggregationKeys(
               ToAggregationKeysEntries(registration.aggregation_keys))
           .SetExpiry(registration.expiry.InSeconds())
-          .SetEventReportWindows(
-              ToEventReportWindows(registration.event_report_windows))
+          // TODO(crbug.com/1499890): Replace defaults with
+          // `registration.trigger_specs` once that field is added.
+          .SetTriggerSpecs(
+              ToTriggerSpecs(attribution_reporting::TriggerSpecs::Default(
+                  common_info.source_type(),
+                  registration.event_report_windows)))
           .SetAggregatableReportWindow(
               registration.aggregatable_report_window.InSeconds())
           .SetTriggerDataMatching(ToTriggerDataMatching(
diff --git a/content/browser/hid/hid_service_unittest.cc b/content/browser/hid/hid_service_unittest.cc
index f9c713b..19dc0aa 100644
--- a/content/browser/hid/hid_service_unittest.cc
+++ b/content/browser/hid/hid_service_unittest.cc
@@ -997,6 +997,13 @@
         .WillOnce(Return(device.get()));
   }
 
+  base::RunLoop disconnect_loop;
+  auto disconnect_closure =
+      base::BarrierClosure(num_devices, disconnect_loop.QuitClosure());
+  for (auto& connection : connections) {
+    connection.set_disconnect_handler(disconnect_closure);
+  }
+
   base::RunLoop run_loop;
   auto barrier = base::BarrierClosure(num_devices, run_loop.QuitClosure());
   url::Origin origin = url::Origin::Create(GURL(kTestUrl));
@@ -1007,7 +1014,12 @@
       .WillRepeatedly(RunClosure(barrier));
   hid_delegate().OnPermissionRevoked(origin);
 
+  run_loop.Run();
+  disconnect_loop.Run();
   CheckHidServiceConnectedState(service_creation_type, false);
+  for (auto& connection : connections) {
+    EXPECT_FALSE(connection.is_connected());
+  }
 }
 
 TEST_P(HidServiceTest, OpenDevicesThenHidServiceReset) {
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc
index 6bdfbca..29d04173 100644
--- a/content/browser/loader/navigation_url_loader_impl.cc
+++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -665,10 +665,10 @@
     next_interceptor->MaybeCreateLoader(
         *resource_request_, browser_context_,
         base::BindOnce(&NavigationURLLoaderImpl::MaybeStartLoader,
-                       base::Unretained(this), next_interceptor),
+                       weak_factory_.GetWeakPtr(), next_interceptor),
         base::BindOnce(
             &NavigationURLLoaderImpl::FallbackToNonInterceptedRequest,
-            base::Unretained(this)));
+            weak_factory_.GetWeakPtr()));
     return;
   }
 
diff --git a/content/browser/preloading/prerender/prerender_browsertest.cc b/content/browser/preloading/prerender/prerender_browsertest.cc
index 63944c3e..dbcd2b6 100644
--- a/content/browser/preloading/prerender/prerender_browsertest.cc
+++ b/content/browser/preloading/prerender/prerender_browsertest.cc
@@ -386,11 +386,18 @@
     prerender_helper_->AddPrefetchAsync(prefetch_url);
   }
 
-  void AddMultiplePrerenderAsync(const std::vector<GURL>& prerendering_urls) {
+  void AddPrerendersAsync(const std::vector<GURL>& prerendering_urls) {
     prerender_helper_->AddPrerendersAsync(prerendering_urls, absl::nullopt,
                                           std::string());
   }
 
+  void AddPrerendersAsync(const std::vector<GURL>& prerendering_urls,
+                          blink::mojom::SpeculationEagerness eagerness,
+                          const std::string& target_hint) {
+    prerender_helper_->AddPrerendersAsync(prerendering_urls, eagerness,
+                                          target_hint);
+  }
+
   void AddPrerenderWithTargetHintAsync(const GURL& prerendering_url,
                                        const std::string& target_hint) {
     prerender_helper_->AddPrerendersAsync({prerendering_url}, absl::nullopt,
@@ -5368,7 +5375,7 @@
   SequentialPrerenderObserver observer(*web_contents(), prerender_urls[2]);
 
   // Insert 3 URLs into the speculation rules at the same time.
-  AddMultiplePrerenderAsync(prerender_urls);
+  AddPrerendersAsync(prerender_urls);
 
   // Wait for DidFinishNavigation on the last URL.
   observer.WaitForTargetNavigationFinished();
@@ -5429,7 +5436,7 @@
 
   // Insert 3 URLs into the speculation rules at the same time. The first
   // prerender should start immediately, and the other two requests enqueued.
-  AddMultiplePrerenderAsync({kPrerender1, kPrerender2, kPrerender3});
+  AddPrerendersAsync({kPrerender1, kPrerender2, kPrerender3});
 
   registry_observer.WaitForTrigger(kPrerender3);
   test::PrerenderHostObserver prerender3_observer(*web_contents(),
@@ -5494,7 +5501,7 @@
 
   // Insert 3 URLs into the speculation rules at the same time. The first
   // prerender should start immediately.
-  AddMultiplePrerenderAsync({kPrerender1, kPrerender2, kPrerender3});
+  AddPrerendersAsync({kPrerender1, kPrerender2, kPrerender3});
 
   // Stop the second prerendering initial navigation.
   response2.WaitForRequest();
@@ -5539,7 +5546,7 @@
   test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());
 
   // Insert 2 URLs into the speculation rules at the same time.
-  AddMultiplePrerenderAsync({kPrerender1, kPrerender2});
+  AddPrerendersAsync({kPrerender1, kPrerender2});
 
   registry_observer.WaitForTrigger(kPrerender2);
   test::PrerenderHostObserver prerender2_observer(*web_contents(),
@@ -5607,7 +5614,7 @@
   test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());
 
   // Insert 5 URLs into the speculation rules at the same time.
-  AddMultiplePrerenderAsync(prerender_urls);
+  AddPrerendersAsync(prerender_urls);
 
   // Stop the first prerendering initial navigation.
   response.WaitForRequest();
@@ -5640,7 +5647,7 @@
   ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl));
 
   // Insert 2 URLs into the speculation rules at the same time.
-  AddMultiplePrerenderAsync({kPrerender1, kPrerender2});
+  AddPrerendersAsync({kPrerender1, kPrerender2});
 
   // Stop the first prerender's initial navigation.
   prerender1_response.WaitForRequest();
@@ -5725,7 +5732,7 @@
   test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());
 
   // Insert 2 URLs into the speculation rules at the same time.
-  AddMultiplePrerenderAsync({kPrerender1, kPrerender2});
+  AddPrerendersAsync({kPrerender1, kPrerender2});
 
   registry_observer.WaitForTrigger(kPrerender2);
   test::PrerenderHostObserver prerender2_observer(*web_contents(),
@@ -5840,7 +5847,7 @@
   test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());
 
   // Insert 2 URLs into the speculation rules at the same time.
-  AddMultiplePrerenderAsync({kPrerender1, kPrerender2});
+  AddPrerendersAsync({kPrerender1, kPrerender2});
   registry_observer.WaitForTrigger(kPrerender2);
 
   // Stop the first prerendering initial navigation.
@@ -5933,7 +5940,7 @@
   test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());
 
   // Insert 3 URLs into the speculation rules at the same time.
-  AddMultiplePrerenderAsync({kPrerender1, kPrerender2, kPrerender3});
+  AddPrerendersAsync({kPrerender1, kPrerender2, kPrerender3});
   registry_observer.WaitForTrigger(kPrerender3);
   test::PrerenderHostObserver prerender1_observer(*web_contents(),
                                                   GetHostForUrl(kPrerender1));
@@ -6001,7 +6008,7 @@
   test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());
 
   // Insert 4 URLs into the speculation rules at the same time.
-  AddMultiplePrerenderAsync(prerender_urls);
+  AddPrerendersAsync(prerender_urls);
   registry_observer.WaitForTrigger(prerender_urls[3]);
 
   // Stop the third prerendering initial navigation.
@@ -6190,7 +6197,7 @@
   test::PrerenderHostRegistryObserver registry_observer(*web_contents_impl());
 
   // Insert 2 URLs into the speculation rules at the same time.
-  AddMultiplePrerenderAsync({kPrerender1, kPrerender2});
+  AddPrerendersAsync({kPrerender1, kPrerender2});
   registry_observer.WaitForTrigger(kPrerender2);
 
   test::PrerenderHostObserver prerender2_observer(*web_contents(),
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc
index d0d604340..26a8dfd 100644
--- a/content/browser/renderer_host/delegated_frame_host.cc
+++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -380,11 +380,12 @@
     return;
   }
 
-  // If we have a surface from before a navigation and we are not in BFCache,
-  // evict it as well.
-  if (!bfcache_fallback_.is_valid() &&
-      pre_navigation_local_surface_id_.is_valid() &&
+  // If we have a surface from before a navigation, evict it as well.
+  if (pre_navigation_local_surface_id_.is_valid() &&
       !first_local_surface_id_after_navigation_.is_valid()) {
+    // If we have a valid `pre_navigation_local_surface_id_`, we must not be in
+    // BFCache.
+    CHECK(!bfcache_fallback_.is_valid());
     EvictDelegatedFrame(frame_evictor_->CollectSurfaceIdsForEviction());
   }
 
@@ -566,13 +567,16 @@
 
 void DelegatedFrameHost::DidEnterBackForwardCache() {
   if (local_surface_id_.is_valid()) {
-    // Resize while hidden (`EmbedSurface` called after
-    // `DidNavigateMainFramePreCommit` and before `DidEnterBackForwardCache`).
+    // `EmbedSurface` can be called after `DidNavigateMainFramePreCommit` and
+    // before `DidEnterBackForwardCache`. This can happen on Mac where the
+    // `DelegatedFrameHost` receives an `EmbedSurface` call directly from
+    // NSView; this can also happen if there is an on-going Hi-DPI capture on
+    // the old frame (see `WebContentsFrameTracker::RenderFrameHostChanged()`).
     //
-    // The `EmbedSurface` for the resize will invalidate
-    // `pre_navigation_local_surface_id_`. In this case we shouldn't restore the
-    // `local_surface_id_` because the surface with a different size should have
-    // a new ID.
+    // The `EmbedSurface` will invalidate `pre_navigation_local_surface_id_`. In
+    // this case we shouldn't restore the `local_surface_id_` nor
+    // `bfcache_fallback_`because the surface should embed the latest
+    // `local_surface_id_`.
     CHECK(!pre_navigation_local_surface_id_.is_valid());
     CHECK(!bfcache_fallback_.is_valid());
   } else {
diff --git a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
index 6e1149b..3a7e6b7d 100644
--- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
+++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -7598,6 +7598,8 @@
             /*ignore_outstanding_network_request=*/false);
     enabled_features.push_back(
         {blink::features::kViewTransitionOnNavigation, {{}}});
+    enabled_features.push_back(
+        {features::kInvalidateLocalSurfaceIdPreCommit, {{}}});
     scoped_feature_list_.InitWithFeaturesAndParameters(
         enabled_features,
         GetDefaultDisabledBackForwardCacheFeaturesForTesting());
@@ -7628,12 +7630,16 @@
 // visual glitches.
 //
 // TODO(https://crbug.com/1472026): Investigate and re-enable.
-//
-// TODO(https://crbug.com/1487799): Disabled globally as the killswitch has been
-// flipped. Re-enable once the proper fix for VT+BFCache has landed.
+#if BUILDFLAG(IS_WIN)
+#define MAYBE_NewContentTimeoutIsSetWhenLeavingBFCacheWithViewTransition \
+  DISABLED_NewContentTimeoutIsSetWhenLeavingBFCacheWithViewTransition
+#else
+#define MAYBE_NewContentTimeoutIsSetWhenLeavingBFCacheWithViewTransition \
+  NewContentTimeoutIsSetWhenLeavingBFCacheWithViewTransition
+#endif
 IN_PROC_BROWSER_TEST_F(
     RenderFrameHostImplBrowserTestWithBFCacheAndViewTransition,
-    DISABLED_NewContentTimeoutIsSetWhenLeavingBFCacheWithViewTransition) {
+    MAYBE_NewContentTimeoutIsSetWhenLeavingBFCacheWithViewTransition) {
   // "red_jank_second_pageshow.html" janks the renderer on the second pageshow
   // event.
   const GURL url_red(embedded_test_server()->GetURL(
@@ -7650,13 +7656,14 @@
   ASSERT_FALSE(rfh_red.IsDestroyed());
   ASSERT_TRUE(
       static_cast<RenderFrameHostImpl*>(rfh_red.get())->IsInBackForwardCache());
+  auto* rwhi_red =
+      RenderWidgetHostImpl::From(rfh_red->GetView()->GetRenderWidgetHost());
+  // The BFCached `RenderWidgetHostImpl` must have a stopped timer.
+  ASSERT_FALSE(rwhi_red->IsContentRenderingTimeoutRunning());
 
   // Navigate back to Red.
   ASSERT_TRUE(HistoryGoBack(web_contents()));
   ASSERT_EQ(rfh_red.get(), web_contents()->GetPrimaryMainFrame());
-
-  RenderWidgetHostImpl* rwhi_red =
-      RenderWidgetHostImpl::From(rfh_red->GetView()->GetRenderWidgetHost());
   ASSERT_TRUE(rwhi_red->IsContentRenderingTimeoutRunning());
 
   gfx::Image screenshot;
diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc
index 583ca65..7f52666c 100644
--- a/content/browser/renderer_host/render_frame_host_manager.cc
+++ b/content/browser/renderer_host/render_frame_host_manager.cc
@@ -4487,9 +4487,8 @@
       }
     }
 
-    StoredPage::StoredPage::RenderViewHostImplSafeRefSet
-        render_view_hosts_to_restore =
-            pending_stored_page->TakeRenderViewHosts();
+    StoredPage::RenderViewHostImplSafeRefSet render_view_hosts_to_restore =
+        pending_stored_page->TakeRenderViewHosts();
     if (prev_state ==
         RenderFrameHostImpl::LifecycleStateImpl::kInBackForwardCache) {
       for (const auto& rvh : render_view_hosts_to_restore) {
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index eeb160ca..5cf9571f0 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -1478,10 +1478,15 @@
   }
 }
 
-void RenderWidgetHostViewAndroid::DidNavigateMainFramePreCommit() {
+void RenderWidgetHostViewAndroid::OnOldViewDidNavigatePreCommit() {
+  if (delegated_frame_host_) {
+    delegated_frame_host_->DidNavigateMainFramePreCommit();
+  }
+}
+
+void RenderWidgetHostViewAndroid::OnNewViewDidNavigatePostCommit() {
   // Move to front only if we are the primary page (we don't want to receive
-  // events in the Prerender). GetMainRenderFrameHost() may be null in
-  // tests.
+  // events in the Prerender). GetMainRenderFrameHost() may be null in tests.
   if (view_.parent() &&
       RenderViewHostImpl::From(host())->GetMainRenderFrameHost() &&
       RenderViewHostImpl::From(host())
@@ -1491,8 +1496,6 @@
     view_.parent()->MoveToFront(&view_);
   }
   ResetGestureDetection();
-  if (delegated_frame_host_)
-    delegated_frame_host_->DidNavigateMainFramePreCommit();
 }
 
 void RenderWidgetHostViewAndroid::DidEnterBackForwardCache() {
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h
index ab61bf2..15240b7 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -198,7 +198,8 @@
   bool CanSynchronizeVisualProperties() override;
   std::unique_ptr<SyntheticGestureTarget> CreateSyntheticGestureTarget()
       override;
-  void DidNavigateMainFramePreCommit() override;
+  void OnOldViewDidNavigatePreCommit() override;
+  void OnNewViewDidNavigatePostCommit() override;
   void DidEnterBackForwardCache() override;
   const viz::FrameSinkId& GetFrameSinkId() const override;
   viz::FrameSinkId GetRootFrameSinkId() override;
diff --git a/content/browser/renderer_host/render_widget_host_view_android_unittest.cc b/content/browser/renderer_host/render_widget_host_view_android_unittest.cc
index 60a766fa..e6957a5 100644
--- a/content/browser/renderer_host/render_widget_host_view_android_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android_unittest.cc
@@ -403,7 +403,7 @@
 
   // Pre-commit information of Navigation is not told to RWHVA, these are the
   // two entry points. We should have a new Surface afterwards.
-  rwhva->DidNavigateMainFramePreCommit();
+  rwhva->OnOldViewDidNavigatePreCommit();
   rwhva->DidNavigate();
   GetLocalSurfaceIdAndConfirmNewerThan(initial_local_surface_id);
 }
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index a0298358..40347e8 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -2783,12 +2783,15 @@
       selection_controller_client_.get(), tsc_config);
 }
 
-void RenderWidgetHostViewAura::DidNavigateMainFramePreCommit() {
+void RenderWidgetHostViewAura::OnOldViewDidNavigatePreCommit() {
   DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
 
   // Invalidate the surface so that we don't attempt to evict it multiple times.
   window_->InvalidateLocalSurfaceId();
   delegated_frame_host_->DidNavigateMainFramePreCommit();
+}
+
+void RenderWidgetHostViewAura::OnNewViewDidNavigatePostCommit() {
   CancelActiveTouches();
 }
 
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index f8a8894f..1d36e35 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -190,7 +190,8 @@
   void ResetFallbackToFirstNavigationSurface() override;
   bool RequestRepaintForTesting() override;
   void DidStopFlinging() override;
-  void DidNavigateMainFramePreCommit() override;
+  void OnOldViewDidNavigatePreCommit() override;
+  void OnNewViewDidNavigatePostCommit() override;
   void DidEnterBackForwardCache() override;
   const viz::FrameSinkId& GetFrameSinkId() const override;
   const viz::LocalSurfaceId& GetLocalSurfaceId() const override;
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc
index 94d403b..8410542 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.cc
+++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -676,7 +676,9 @@
   return;
 }
 
-void RenderWidgetHostViewBase::DidNavigateMainFramePreCommit() {}
+void RenderWidgetHostViewBase::OnOldViewDidNavigatePreCommit() {}
+
+void RenderWidgetHostViewBase::OnNewViewDidNavigatePostCommit() {}
 
 void RenderWidgetHostViewBase::OnFrameTokenChangedForView(
     uint32_t frame_token,
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h
index 955f08e2..7c84c4de 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.h
+++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -500,12 +500,35 @@
   // Gets the bounds of the top-level window, in screen coordinates.
   virtual gfx::Rect GetBoundsInRootWindow() = 0;
 
-  // Dispatched when the main frame associated with a `RenderWidgetHostView` is
-  // being navigated to a different Document (won't be dispatched for
-  // same-document navigations).
+  // Dispatched when the a cross-document navigation happens in the primary main
+  // frame, and the old view is still visible. This API is called on the old
+  // view.
   //
-  // "PreCommit" means the new page hasn't been marked as visible yet.
-  virtual void DidNavigateMainFramePreCommit();
+  // "DidNavigate" means this API (and its post commit counterpart) is part of
+  // the browser's atomic "DidCommitNavigation" stack. "PreCommit" means the old
+  // view is still visible and the new view is still invisible.
+  //
+  // The platform-specific overrides should prepare for the old view about to be
+  // swapped out, which typically includes resetting the graphical states on the
+  // old view.
+  //
+  // This API shouldn't be called for a same-doc navigations. For the cross-doc
+  // navigations that don't swap the `RenderWidgetHostView`, the old and new
+  // views are the same.
+  virtual void OnOldViewDidNavigatePreCommit();
+
+  // Dispatched when the new primary main frame's `RenderWidgetHostView` is
+  // swapped in, and is made visible due to a cross-document navigation. This
+  // API is called on the new view.
+  //
+  // The platform-specific overrides should prepare for the new view about to be
+  // made visible, which typically includes cancelling any ongoing gesture
+  // events.
+  //
+  // Same as its pre commit counterpart: this API shouldn't be called for
+  // same-doc navigations, and the new view can be the same as the old view if
+  // the navigation does not swap the `RenderWidgetHostView`.
+  virtual void OnNewViewDidNavigatePostCommit();
 
   // Gives a chance to the caller to perform some task AFTER the page is
   // unloaded and stored in the BFCache.
diff --git a/content/browser/renderer_host/render_widget_host_view_browsertest.cc b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
index 6b4f9e4..0157be58 100644
--- a/content/browser/renderer_host/render_widget_host_view_browsertest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
@@ -43,6 +43,7 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_paths.h"
+#include "content/public/common/content_switches.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/test/back_forward_cache_util.h"
 #include "content/public/test/browser_test.h"
@@ -1541,6 +1542,7 @@
   void CreateVisibleTimeRequest(bool show_reason_tab_switching = true,
                                 bool show_reason_bfcache_restore = false) {
     if (show_reason_bfcache_restore) {
+      GetRenderWidgetHostView()->OnOldViewDidNavigatePreCommit();
       GetRenderWidgetHostView()->DidEnterBackForwardCache();
     }
     GetRenderWidgetHostView()
@@ -1884,4 +1886,239 @@
                          ::testing::Bool());
 #endif
 
+namespace {
+
+// When an OOPIF performs a "location.replace" main frame navigation and with
+// BFCache enabled, it can lead to a redundant `ui::ViewAndroid` attached under
+// `WebContentsViewAndroid` (*), even though the OOPIF and its embedding main
+// frame are stored in BFCache, the redundant `ui::ViewAndroid` is not detached
+// properly.
+//
+// *: Also the case for Aura with duplicated `ui::Window`; unclear about other
+//    platforms.
+//
+// The root cause:
+// 1. The "location.replace" first signals the browser that we will not swap the
+//    BrowsingInstance.
+// 2. Since BI is not swapped (yet), the speculative RFH can be in the same
+//    SiteInstanceGroup as the RFH of the OOPIF (i.e., both being b.com). Same
+//    SIGroup means the speculative RFH and the OOPIF RFH ref-count the same
+//    `RenderViewHost`.
+// 3. And since this is a main frame navigation, we create a new RWHV (and a
+//    `gfx::NativeView`) for the speculative RFH. Now OOPIF and the speculative
+//    RFH share the same RVH and RWHV. 2 and 3 happen before the browser hear
+//    back from the server with the header.
+// 4. The server responds with the header "coop=same-site". The browser now
+//    realizes the BI needs to be swapped. The old page and the OOPIF are
+//    BFCached, but the OOPIF still has reference to a RWHV/NativeView that it
+//    shouldn't have.
+//
+// TODO(https://crbug.com/1492600):
+// - A page shouldn't be BFCached if it is no longer reachable via session
+//   history navigations (i.e., if the navigation entry is replaced).
+// - When the browser is in a steady state with no on-going navigations, there
+//   should only be one `RenderWidgetHostView` for the main frame, one only one
+//   `gfx::NativeView` under the WebContents.
+class RenderWidgetHostViewOOPIFNavigatesMainFrameLocationReplaceBrowserTest
+    : public RenderWidgetHostViewBrowserTest,
+      public ::testing::WithParamInterface<bool> {
+ public:
+  RenderWidgetHostViewOOPIFNavigatesMainFrameLocationReplaceBrowserTest() =
+      default;
+  ~RenderWidgetHostViewOOPIFNavigatesMainFrameLocationReplaceBrowserTest()
+      override = default;
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    // For OOPIF. a.test, b.test etc will be in their respective
+    // `SiteInstanceGroup`s.
+    command_line->AppendSwitch(switches::kSitePerProcess);
+
+    std::vector<base::test::FeatureRefAndParams> enabled_features;
+    base::test::FeatureRefAndParams must_enable(
+        /*feature=*/features::kInvalidateLocalSurfaceIdPreCommit,
+        /*params=*/std::map<std::string, std::string>());
+    enabled_features.push_back(std::move(must_enable));
+
+    bool bfcache_enabled = GetParam();
+    if (bfcache_enabled) {
+      scoped_feature_list_.InitWithFeaturesAndParameters(
+          GetDefaultEnabledBackForwardCacheFeaturesForTesting(enabled_features),
+          GetDefaultDisabledBackForwardCacheFeaturesForTesting());
+    } else {
+      scoped_feature_list_.InitWithFeaturesAndParameters(enabled_features, {});
+      command_line->AppendSwitch(switches::kDisableBackForwardCache);
+    }
+
+    RenderWidgetHostViewBrowserTest::SetUpCommandLine(command_line);
+  }
+
+  void SetUpOnMainThread() override {
+    ASSERT_TRUE(AreAllSitesIsolatedForTesting());
+
+    host_resolver()->AddRule("*", "127.0.0.1");
+
+    https_server()->ServeFilesFromSourceDirectory(GetTestDataFilePath());
+    https_server()->SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
+    net::test_server::RegisterDefaultHandlers(https_server());
+
+    ASSERT_TRUE(https_server()->Start());
+  }
+
+  bool SetUpSourceSurface(const char* wait_message) override { return false; }
+
+  RenderFrameHostImpl* AddSubframe(WebContentsImpl* web_contents,
+                                   const GURL& url) {
+    auto* main_frame = web_contents->GetPrimaryMainFrame();
+
+    static constexpr char kAddIFrame[] = R"({
+        const iframe = document.createElement('iframe');
+        iframe.src = $1;
+        document.body.appendChild(iframe);
+      })";
+    TestNavigationObserver observer(web_contents);
+    EXPECT_TRUE(ExecJs(main_frame, JsReplace(kAddIFrame, url)));
+    observer.Wait();
+    EXPECT_EQ(main_frame->frame_tree_node()->child_count(), 1U);
+    return main_frame->frame_tree_node()->child_at(0u)->current_frame_host();
+  }
+
+  void NavigateMainFrameFromSubframeAndWait(RenderFrameHost* subframe_rfh,
+                                            const GURL& url) {
+    TestNavigationObserver observer(web_contents());
+    ASSERT_TRUE(ExecJs(subframe_rfh,
+                       JsReplace("window.top.location.replace($1)", url)));
+    observer.Wait();
+  }
+
+  net::EmbeddedTestServer* https_server() { return &https_server_; }
+
+  WebContentsImpl* web_contents() {
+    return static_cast<WebContentsImpl*>(shell()->web_contents());
+  }
+
+ private:
+  net::EmbeddedTestServer https_server_{
+      net::EmbeddedTestServer::Type::TYPE_HTTPS};
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+std::string DescribeBFCacheFeatureStatus(
+    const ::testing::TestParamInfo<bool>& info) {
+  if (info.param) {
+    return "BFCache_Enabled";
+  } else {
+    return "BFCache_Disabled";
+  }
+}
+
+}  // namespace
+
+// TODO(https://crbug.com/1492600): When fix the BFCache behavior, move this
+// test into "back_forward_cache_basics_browsertest.cc". Temporarily placed here
+// to reuse the testing harness.
+IN_PROC_BROWSER_TEST_P(
+    RenderWidgetHostViewOOPIFNavigatesMainFrameLocationReplaceBrowserTest,
+    NonHistoryTraversablePageShouldNotBeBFCached) {
+  ASSERT_TRUE(NavigateToURL(web_contents(),
+                            https_server()->GetURL("a.test", "/title1.html")));
+
+  RenderFrameHostWrapper subframe_rfh(AddSubframe(
+      web_contents(), https_server()->GetURL("b.test", "/title2.html")));
+  RenderFrameHostWrapper old_main_frame(web_contents()->GetPrimaryMainFrame());
+
+  NavigateMainFrameFromSubframeAndWait(
+      subframe_rfh.get(),
+      https_server()->GetURL(
+          "b.test", "/set-header?Cross-Origin-Opener-Policy: same-origin"));
+
+  // Location.replace navigaion replaces the navigation entry of the old page.
+  // We can't go back.
+  ASSERT_EQ(web_contents()->GetPrimaryFrameTree().controller().GetEntryCount(),
+            1);
+
+  bool bfcache_enabled = GetParam();
+  if (bfcache_enabled) {
+    // TODO(https://crbug.com/1492600): We shouldn't store the old page and its
+    // OOPIF in the BFCache.
+    ASSERT_FALSE(old_main_frame.IsDestroyed());
+    ASSERT_FALSE(subframe_rfh.IsDestroyed());
+    ASSERT_TRUE(static_cast<RenderFrameHostImpl*>(old_main_frame.get())
+                    ->IsInBackForwardCache());
+    ASSERT_TRUE(static_cast<RenderFrameHostImpl*>(subframe_rfh.get())
+                    ->IsInBackForwardCache());
+  } else {
+    ASSERT_TRUE(old_main_frame.WaitUntilRenderFrameDeleted());
+    ASSERT_TRUE(subframe_rfh.WaitUntilRenderFrameDeleted());
+  }
+}
+
+// Regression test for b/302490197: the touch events should always be forwarded
+// to the main frame's `RenderWidgetHostViewAndroid` and its `ui::ViewAndroid`,
+// no matter if there are redundant RWHVAs / VAs under the same WebContents.
+#if BUILDFLAG(IS_ANDROID)
+IN_PROC_BROWSER_TEST_P(
+    RenderWidgetHostViewOOPIFNavigatesMainFrameLocationReplaceBrowserTest,
+    TouchEventsForwardedToTheCorrectRenderWidgetHostView) {
+  ASSERT_TRUE(NavigateToURL(web_contents(),
+                            https_server()->GetURL("a.test", "/title1.html")));
+
+  RenderFrameHostWrapper subframe_rfh(AddSubframe(
+      web_contents(), https_server()->GetURL("b.test", "/title2.html")));
+  RenderFrameHostWrapper old_main_frame(web_contents()->GetPrimaryMainFrame());
+
+  NavigateMainFrameFromSubframeAndWait(
+      subframe_rfh.get(),
+      https_server()->GetURL(
+          "b.test", "/set-header?Cross-Origin-Opener-Policy: same-origin"));
+
+  bool bfcache_enabled = GetParam();
+  if (!bfcache_enabled) {
+    ASSERT_TRUE(old_main_frame.WaitUntilRenderFrameDeleted());
+    ASSERT_TRUE(subframe_rfh.WaitUntilRenderFrameDeleted());
+  }
+
+  // Three RWHV when BFCache is enabled: old main frame and its OOPIF, and the
+  // new main frame.
+  //
+  // TODO(https://crbug.com/1492600): The number of RWHVs should be one,
+  // regardless of BFCache.
+  size_t num_expected_rwhv = bfcache_enabled ? 3u : 1u;
+  size_t num_actual_rwhv = 0u;
+  static_cast<WebContents*>(web_contents())
+      ->ForEachRenderFrameHost([&num_actual_rwhv](RenderFrameHost* rfh) {
+        if (rfh->GetView()) {
+          ++num_actual_rwhv;
+        }
+      });
+  ASSERT_EQ(num_actual_rwhv, num_expected_rwhv);
+
+  // On Android, when the old main frame is unloaded, we explicitly call
+  // `RWHVA::UpdateNativeViewTree()` to remove the old main frame's native
+  // view from the native view tree. Thus the number of ViewAndroids is two
+  // instead of three, when the old main frame and the OOPIF are BFCached. See
+  // `WebContentsViewAndroid::RenderViewHostChanged()`.
+  //
+  // TODO(https://crbug.com/1492600): The number of `ui::ViewAndroid`s should be
+  // one, regardless of BFCache.
+  size_t num_expected_native_view = bfcache_enabled ? 2u : 1u;
+  auto* web_contents_view_android =
+      static_cast<ui::ViewAndroid*>(web_contents()->GetNativeView());
+
+  ASSERT_EQ(web_contents_view_android->GetChildrenCountForTesting(),
+            num_expected_native_view);
+  // b/302490197: The top-most child `gfx::NativeView` under the WebContents
+  // should be the one of the primary main frame, regardless if any other
+  // siblings exist. This native view of the primary main frame is responsible
+  // for receiving gesture events, thus has to be the top-most.
+  ASSERT_EQ(web_contents_view_android->GetTopMostChildForTesting(),
+            web_contents()->GetPrimaryMainFrame()->GetNativeView());
+}
+#endif  // BUILDFLAG(IS_ANDROID)
+
+INSTANTIATE_TEST_SUITE_P(
+    All,
+    RenderWidgetHostViewOOPIFNavigatesMainFrameLocationReplaceBrowserTest,
+    testing::Bool(),
+    &DescribeBFCacheFeatureStatus);
+
 }  // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_view_ios.h b/content/browser/renderer_host/render_widget_host_view_ios.h
index 2cae8de..a4e25879 100644
--- a/content/browser/renderer_host/render_widget_host_view_ios.h
+++ b/content/browser/renderer_host/render_widget_host_view_ios.h
@@ -112,7 +112,8 @@
   void CancelSuccessfulPresentationTimeRequestForHostAndDelegate() override;
   viz::ScopedSurfaceIdAllocator DidUpdateVisualProperties(
       const cc::RenderFrameMetadata& metadata) override;
-  void DidNavigateMainFramePreCommit() override;
+  void OnOldViewDidNavigatePreCommit() override;
+  void OnNewViewDidNavigatePostCommit() override;
   void DidEnterBackForwardCache() override;
   void DidNavigate() override;
   bool RequestRepaintForTesting() override;
diff --git a/content/browser/renderer_host/render_widget_host_view_ios.mm b/content/browser/renderer_host/render_widget_host_view_ios.mm
index 80518f7..df3e672 100644
--- a/content/browser/renderer_host/render_widget_host_view_ios.mm
+++ b/content/browser/renderer_host/render_widget_host_view_ios.mm
@@ -643,10 +643,16 @@
   display_tree_->UpdateCALayerTree(ca_layer_params);
 }
 
-void RenderWidgetHostViewIOS::DidNavigateMainFramePreCommit() {
-  CHECK(browser_compositor_) << "Shouldn't be called during destruction!";
+void RenderWidgetHostViewIOS::OnOldViewDidNavigatePreCommit() {
+  if (base::FeatureList::IsEnabled(
+          features::kInvalidateLocalSurfaceIdPreCommit)) {
+    CHECK(browser_compositor_) << "Shouldn't be called during destruction!";
+    browser_compositor_->DidNavigateMainFramePreCommit();
+  }
+}
+
+void RenderWidgetHostViewIOS::OnNewViewDidNavigatePostCommit() {
   gesture_provider_.ResetDetection();
-  browser_compositor_->DidNavigateMainFramePreCommit();
 }
 
 void RenderWidgetHostViewIOS::DidEnterBackForwardCache() {
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h
index 223b88f..90d8ab3 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.h
+++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -132,7 +132,8 @@
   void UpdateCursor(const ui::Cursor& cursor) override;
   void DisplayCursor(const ui::Cursor& cursor) override;
   CursorManager* GetCursorManager() override;
-  void DidNavigateMainFramePreCommit() override;
+  void OnOldViewDidNavigatePreCommit() override;
+  void OnNewViewDidNavigatePostCommit() override;
   void DidEnterBackForwardCache() override;
   void SetIsLoading(bool is_loading) override;
   void RenderProcessGone() override;
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index aad75b3..c260544 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -620,15 +620,18 @@
   return cursor_manager_.get();
 }
 
-void RenderWidgetHostViewMac::DidNavigateMainFramePreCommit() {
-  CHECK(browser_compositor_) << "Shouldn't be called during destruction!";
-  gesture_provider_.ResetDetection();
+void RenderWidgetHostViewMac::OnOldViewDidNavigatePreCommit() {
   if (base::FeatureList::IsEnabled(
           features::kInvalidateLocalSurfaceIdPreCommit)) {
+    CHECK(browser_compositor_) << "Shouldn't be called during destruction!";
     browser_compositor_->DidNavigateMainFramePreCommit();
   }
 }
 
+void RenderWidgetHostViewMac::OnNewViewDidNavigatePostCommit() {
+  gesture_provider_.ResetDetection();
+}
+
 void RenderWidgetHostViewMac::DidEnterBackForwardCache() {
   CHECK(browser_compositor_) << "Shouldn't be called during destruction!";
   browser_compositor_->DidEnterBackForwardCache();
diff --git a/content/browser/resources/BUILD.gn b/content/browser/resources/BUILD.gn
index f0f2edc..f4f7f83 100644
--- a/content/browser/resources/BUILD.gn
+++ b/content/browser/resources/BUILD.gn
@@ -18,7 +18,7 @@
     "service_worker:resources",
   ]
 
-  if (!is_android) {
+  if (!is_android && !is_ios) {
     public_deps += [ "traces_internals:resources" ]
   }
 
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index d57a64e5..ed7e2784 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -6449,7 +6449,7 @@
     auto* rwhvb = static_cast<RenderWidgetHostViewBase*>(
         frame_tree_node->current_frame_host()->GetView());
     if (rwhvb) {
-      rwhvb->DidNavigateMainFramePreCommit();
+      rwhvb->OnOldViewDidNavigatePreCommit();
     }
   }
 
@@ -6467,6 +6467,9 @@
                         "render_frame_host", render_frame_host);
   const bool is_primary_main_frame = render_frame_host->IsInPrimaryMainFrame();
 
+  auto* rwhvb = static_cast<RenderWidgetHostViewBase*>(
+      render_frame_host->GetMainFrame()->GetView());
+
   if (details.is_navigation_to_different_page()) {
     if (is_primary_main_frame) {
       // Clear the status bubble. This is a workaround for a bug where WebKit
@@ -6476,15 +6479,26 @@
       // clear the bubble when a user navigates to a named anchor in the same
       // page.
       ClearTargetURL();
+
+      // If the feature flag is enabled, we only call the PostCommit on the new
+      // View, for a primary main frame navigation. The PreCommit counterpart is
+      // called in `WCImpl:DidNavigateMainFramePreCommit`.
+      if (rwhvb && base::FeatureList::IsEnabled(
+                       features::kInvalidateLocalSurfaceIdPreCommit)) {
+        rwhvb->OnNewViewDidNavigatePostCommit();
+      }
     }
 
-    if (!base::FeatureList::IsEnabled(
-            features::kInvalidateLocalSurfaceIdPreCommit)) {
-      RenderWidgetHostViewBase* rwhvb = static_cast<RenderWidgetHostViewBase*>(
-          render_frame_host->GetMainFrame()->GetView());
-      if (rwhvb) {
-        rwhvb->DidNavigateMainFramePreCommit();
-      }
+    // If the feature flag is disabled, we restore to the "original" behavior (
+    // the behavior prior to https://crrev.com/c/4702023):
+    // When the new view is just made visible, we:
+    // - Reset the LocalSurfaceId on the new View (PreCommit), and
+    // - Cancel the ongoing gestures on the new View (PostCommit), and
+    // - We call the two APIs on all main frames, including non-primary ones.
+    if (rwhvb && !base::FeatureList::IsEnabled(
+                     features::kInvalidateLocalSurfaceIdPreCommit)) {
+      rwhvb->OnOldViewDidNavigatePreCommit();
+      rwhvb->OnNewViewDidNavigatePostCommit();
     }
   }
 
diff --git a/content/browser/webui/content_web_ui_configs.cc b/content/browser/webui/content_web_ui_configs.cc
index 17d550f..2cf9174b 100644
--- a/content/browser/webui/content_web_ui_configs.cc
+++ b/content/browser/webui/content_web_ui_configs.cc
@@ -20,7 +20,7 @@
 #include "content/browser/webrtc/webrtc_internals_ui.h"
 #include "content/public/browser/webui_config_map.h"
 
-#if !BUILDFLAG(IS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
 #include "content/browser/tracing/trace_report/trace_report_internals_ui.h"
 #include "content/browser/tracing/tracing_ui.h"
 #endif
@@ -50,7 +50,7 @@
   map.AddWebUIConfig(std::make_unique<WebXrInternalsUIConfig>());
 #endif
 
-#if !BUILDFLAG(IS_ANDROID)
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
   map.AddWebUIConfig(std::make_unique<TraceReportInternalsUIConfig>());
   map.AddWebUIConfig(std::make_unique<TracingUIConfig>());
 #endif
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn
index 0ae53038..1f3988f 100644
--- a/content/public/browser/BUILD.gn
+++ b/content/public/browser/BUILD.gn
@@ -316,6 +316,7 @@
     "preloading_data.h",
     "prerender_handle.h",
     "prerender_trigger_type.h",
+    "prerender_web_contents_delegate.cc",
     "prerender_web_contents_delegate.h",
     "presentation_observer.h",
     "presentation_receiver_flags.h",
diff --git a/content/public/browser/prerender_web_contents_delegate.cc b/content/public/browser/prerender_web_contents_delegate.cc
new file mode 100644
index 0000000..0629520
--- /dev/null
+++ b/content/public/browser/prerender_web_contents_delegate.cc
@@ -0,0 +1,22 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/public/browser/prerender_web_contents_delegate.h"
+
+#include "content/browser/preloading/prerender/prerender_final_status.h"
+#include "content/browser/preloading/prerender/prerender_host_registry.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+
+namespace content {
+
+void PrerenderWebContentsDelegate::CloseContents(WebContents* source) {
+  // Cancelling prerendering should eventually destroy `this` and `source`.
+  // However, this behavior is not implemented yet.
+  // TODO(https://crbug.com/1499759): Implement this behavior.
+  static_cast<WebContentsImpl*>(source)
+      ->GetPrerenderHostRegistry()
+      ->CancelAllHosts(PrerenderFinalStatus::kTabClosedWithoutUserGesture);
+}
+
+}  // namespace content
diff --git a/content/public/browser/prerender_web_contents_delegate.h b/content/public/browser/prerender_web_contents_delegate.h
index a35d9e1d..6d6c868 100644
--- a/content/public/browser/prerender_web_contents_delegate.h
+++ b/content/public/browser/prerender_web_contents_delegate.h
@@ -12,12 +12,14 @@
 // This is used as the delegate of WebContents created for a new tab where
 // prerendering runs. The delegate will be swapped with a proper one on
 // prerender page activation.
-//
-// This class is currently empty but necessary to bypass the "protected"
-// destructor of WebContentsDelegate. Without this indirect class, an owner of
-// WebContentsDelegate implementation in content/ cannot call the destructor.
-// See review comments on https://crrev.com/c/4680866/ for details.
-class PrerenderWebContentsDelegate : public WebContentsDelegate {};
+class CONTENT_EXPORT PrerenderWebContentsDelegate : public WebContentsDelegate {
+ public:
+  PrerenderWebContentsDelegate() = default;
+  ~PrerenderWebContentsDelegate() override = default;
+
+  // WebContentsDelegate overrides.
+  void CloseContents(WebContents* source) override;
+};
 
 }  // namespace content
 
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 9297cf62..d6b10d6 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -78,7 +78,7 @@
 // back/forward cache.
 BASE_FEATURE(kBackForwardCacheMediaSessionService,
              "BackForwardCacheMediaSessionService",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 // Set a time limit for the page to enter the cache. Disabling this prevents
 // flakes during testing.
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 4d902f79..cad3b171 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -6247,9 +6247,19 @@
   AssertNavigationCommits assert_navigation_commits(
       this, kMayReplaceInitialEmptyDocument);
 
+  mojo::PendingRemote<network::mojom::URLLoaderFactory>
+      url_loader_factory_remote;
+  if (url_loader_factory_override_for_test_) {
+    url_loader_factory_override_for_test_->Clone(
+        url_loader_factory_remote.InitWithNewPipeAndPassReceiver());
+  } else {
+    url_loader_factory_remote =
+        network::NotImplementedURLLoaderFactory::Create();
+  }
+
   pending_loader_factories_ = CreateLoaderFactoryBundle(
       blink::ChildPendingURLLoaderFactoryBundle::CreateFromDefaultFactoryImpl(
-          network::NotImplementedURLLoaderFactory::Create()),
+          std::move(url_loader_factory_remote)),
       /*subresource_overrides=*/absl::nullopt,
       /*subresource_proxying_loader_factory=*/{},
       /*keep_alive_loader_factory=*/{},
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index 4253408..c27c82e 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -538,7 +538,7 @@
     sources += [ "$root_gen_dir/content/webxr_internals_resources.pak" ]
   }
 
-  if (!is_android) {
+  if (!is_android && !is_ios) {
     deps += [ "//content/browser/tracing:resources" ]
     sources += [
       "$root_gen_dir/content/browser/tracing/tracing_resources.pak",
diff --git a/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-android-assist-data.txt b/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-android-assist-data.txt
index 01deae1..e4fbca82 100644
--- a/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-android-assist-data.txt
+++ b/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-android-assist-data.txt
@@ -1,13 +1,12 @@
 WebView textSize:16.00 style:0 bundle:[display="", htmlTag="#document"]
-++EditText text:"Important stuff My name is Eli the weird. (QED) Where are my marbles?" textSize:13.33 style:0 bundle:[aria-describedby="descId", aria-label="Important stuff", display="inline-block", htmlTag="input", id="test", type="text"]
+++EditText text:"Important stuff My name is Garaventa the weird. (QED) Where are my marbles?" textSize:13.33 style:0 bundle:[aria-describedby="descId", aria-label="Important stuff", display="inline-block", htmlTag="input", id="test", type="text"]
 ++++View textSize:13.33 style:0 bundle:[display="flow-root", htmlTag="div"]
 ++View textSize:16.00 style:0 bundle:[display="block", htmlTag="div", id="descId"]
 ++++TextView text:"My" textSize:16.00 style:0 bundle:[display="", htmlTag=""]
 ++++TextView text:" name is" textSize:16.00 style:0 bundle:[display="", htmlTag=""]
 ++++View textSize:16.00 style:0 bundle:[display="block", htmlTag="div"]
-++++View text:"Eli" textSize:16.00 style:0 bundle:[aria-label="Eli", display="inline", htmlTag="span", role="presentation"]
-++++++View text:"Garaventa" textSize:16.00 style:0 bundle:[aria-label="Garaventa", display="inline", htmlTag="span"]
-++++++++TextView text:"Zambino" textSize:16.00 style:0 bundle:[display="", htmlTag=""]
+++++View text:"Garaventa" textSize:16.00 style:0 bundle:[aria-label="Garaventa", display="inline", htmlTag="span"]
+++++++TextView text:"Zambino" textSize:16.00 style:0 bundle:[display="", htmlTag=""]
 ++++TextView text:"the weird." textSize:16.00 style:0 bundle:[display="", htmlTag=""]
 ++++TextView text:" (QED)" textSize:16.00 style:0 bundle:[display="", htmlTag=""]
 ++++View textSize:16.00 style:0 bundle:[display="table", htmlTag="table"]
@@ -16,4 +15,4 @@
 ++++++++++TextView text:"Where" textSize:16.00 style:0 bundle:[display="", htmlTag=""]
 ++++++++View textSize:16.00 style:0 bundle:[display="table-cell", htmlTag="td"]
 ++++++++View textSize:16.00 style:0 bundle:[display="table-cell", htmlTag="td"]
-++++++++++TextView text:"are my marbles?" textSize:16.00 style:0 bundle:[display="", htmlTag=""]
+++++++++++TextView text:"are my marbles?" textSize:16.00 style:0 bundle:[display="", htmlTag=""]
\ No newline at end of file
diff --git a/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-android-external.txt b/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-android-external.txt
index e7696a3e..0dc7bb2d 100644
--- a/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-android-external.txt
+++ b/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-android-external.txt
@@ -1,15 +1,14 @@
 WebView focusable focused scrollable actions:[CLEAR_FOCUS, AX_FOCUS] bundle:[chromeRole="rootWebArea"]
-++EditText hint:"Important stuff My name is Eli the weird. (QED) Where are my marbles?" viewIdResName:"test" clickable editable focusable inputType:1 textSelectionStart:0 textSelectionEnd:0 actions:[FOCUS, CLICK, AX_FOCUS, PASTE, SET_TEXT, IME_ENTER] bundle:[chromeRole="textField", clickableScore="300", hint="Important stuff My name is Eli the weird. (QED) Where are my marbles?"]
+++EditText hint:"Important stuff My name is Garaventa the weird. (QED) Where are my marbles?" viewIdResName:"test" clickable editable focusable inputType:1 textSelectionStart:0 textSelectionEnd:0 actions:[FOCUS, CLICK, AX_FOCUS, PASTE, SET_TEXT, IME_ENTER] bundle:[chromeRole="textField", clickableScore="300", hint="Important stuff My name is Garaventa the weird. (QED) Where are my marbles?"]
 ++View viewIdResName:"descId" actions:[AX_FOCUS] bundle:[chromeRole="genericContainer"]
 ++++TextView text:"My" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="staticText"]
 ++++TextView text:" name is" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="staticText"]
 ++++TextView actions:[AX_FOCUS] bundle:[chromeRole="genericContainer"]
-++++View text:"Eli" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="genericContainer"]
-++++++TextView text:"Garaventa" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="genericContainer"]
+++++TextView text:"Garaventa" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="genericContainer"]
 ++++TextView text:"the weird." actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="staticText"]
 ++++TextView text:" (QED)" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="staticText"]
 ++++View actions:[AX_FOCUS] bundle:[chromeRole="layoutTable"]
 ++++++View actions:[AX_FOCUS] bundle:[chromeRole="layoutTableRow"]
 ++++++++View text:"Where" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="layoutTableCell"]
 ++++++++View actions:[AX_FOCUS] bundle:[chromeRole="layoutTableCell"]
-++++++++View text:"are my marbles?" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="layoutTableCell"]
+++++++++View text:"are my marbles?" actions:[AX_FOCUS, NEXT, PREVIOUS] bundle:[chromeRole="layoutTableCell"]
\ No newline at end of file
diff --git a/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-android.txt b/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-android.txt
index 5fc88c7..45164c2 100644
--- a/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-android.txt
+++ b/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-android.txt
@@ -1 +1 @@
-android.widget.EditText hint='Important stuff My name is Eli the weird. (QED) Where are my marbles?' input_type=1
+android.widget.EditText hint='Important stuff My name is Garaventa the weird. (QED) Where are my marbles?' input_type=1
diff --git a/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-auralinux.txt b/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-auralinux.txt
index f9611c1..0a24be06 100644
--- a/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-auralinux.txt
+++ b/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-auralinux.txt
@@ -1 +1 @@
-[entry] description='My name is Eli the weird. (QED) Where are my marbles?' described-by=[section] description-from:aria-describedby
+[entry] description='My name is Garaventa the weird. (QED) Where are my marbles?' described-by=[section] description-from:aria-describedby
diff --git a/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-blink.txt b/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-blink.txt
index 373c598..de4fdc6cf 100644
--- a/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-blink.txt
+++ b/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-blink.txt
@@ -1,4 +1,4 @@
-# Original expectation was missing a space ("Elithe"), but the spec is not
+# Original expectation was missing a space ("Garaventathe"), but the spec is not
 # clear about this and it seems wrong, the result should match the rendered text
 # more closely. See: https://github.com/w3c/accname/issues/15
-textField description='My name is Eli the weird. (QED) Where are my marbles?' descriptionFrom=relatedElement
+textField description='My name is Garaventa the weird. (QED) Where are my marbles?' descriptionFrom=relatedElement
diff --git a/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-mac.txt b/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-mac.txt
index 361094b8..0a71ab99 100644
--- a/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-mac.txt
+++ b/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-mac.txt
@@ -1 +1 @@
-AXTextField accessibilityCustomContent=[{label: 'description', value: 'My name is Eli the weird. (QED) Where are my marbles?'}]
+AXTextField accessibilityCustomContent=[{label: 'description', value: 'My name is Garaventa the weird. (QED) Where are my marbles?'}]
diff --git a/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-win.txt b/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-win.txt
index 311e839..8f35977d 100644
--- a/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-win.txt
+++ b/content/test/data/accessibility/accname/desc-from-content-of-describedby-element-expected-win.txt
@@ -1 +1 @@
-ROLE_SYSTEM_TEXT FOCUSABLE description-from:aria-describedby description='My name is Eli the weird. (QED) Where are my marbles?'
+ROLE_SYSTEM_TEXT FOCUSABLE description-from:aria-describedby description='My name is Garaventa the weird. (QED) Where are my marbles?'
diff --git a/content/test/data/accessibility/accname/name-from-content-expected-blink.txt b/content/test/data/accessibility/accname/name-from-content-expected-blink.txt
index 1d5ba97..bbcfb2ed 100644
--- a/content/test/data/accessibility/accname/name-from-content-expected-blink.txt
+++ b/content/test/data/accessibility/accname/name-from-content-expected-blink.txt
@@ -1,4 +1,4 @@
-# Original expectation was missing a space ("Elithe"), but the spec is not
+# Original expectation was missing a space ("Garaventathe"), but the spec is not
 # clear about this and it seems wrong, the result should match the rendered text
 # more closely. See: https://github.com/w3c/accname/issues/15
-link name='My name is Eli the weird. (QED) Where are my marbles?' nameFrom=contents
+link name='My name is Garaventa the weird. (QED) Where are my marbles?' nameFrom=contents
diff --git a/content/test/data/accessibility/accname/name-from-content-of-label-expected-blink.txt b/content/test/data/accessibility/accname/name-from-content-of-label-expected-blink.txt
index b4bb6b5..d4de3cf 100644
--- a/content/test/data/accessibility/accname/name-from-content-of-label-expected-blink.txt
+++ b/content/test/data/accessibility/accname/name-from-content-of-label-expected-blink.txt
@@ -1,4 +1,4 @@
-# Original expectation was missing a space ("Elithe"), but the spec is not
+# Original expectation was missing a space ("Garaventathe"), but the spec is not
 # clear about this and it seems wrong, the result should match the rendered text
 # more closely. See: https://github.com/w3c/accname/issues/15
-textField name='My name is Eli the weird. (QED) Where are my marbles?' nameFrom=relatedElement
+textField name='My name is Garaventa the weird. (QED) Where are my marbles?' nameFrom=relatedElement
diff --git a/content/test/data/accessibility/accname/name-from-content-of-labelledby-element-expected-blink.txt b/content/test/data/accessibility/accname/name-from-content-of-labelledby-element-expected-blink.txt
index b4bb6b5..d4de3cf 100644
--- a/content/test/data/accessibility/accname/name-from-content-of-labelledby-element-expected-blink.txt
+++ b/content/test/data/accessibility/accname/name-from-content-of-labelledby-element-expected-blink.txt
@@ -1,4 +1,4 @@
-# Original expectation was missing a space ("Elithe"), but the spec is not
+# Original expectation was missing a space ("Garaventathe"), but the spec is not
 # clear about this and it seems wrong, the result should match the rendered text
 # more closely. See: https://github.com/w3c/accname/issues/15
-textField name='My name is Eli the weird. (QED) Where are my marbles?' nameFrom=relatedElement
+textField name='My name is Garaventa the weird. (QED) Where are my marbles?' nameFrom=relatedElement
diff --git a/content/test/data/accessibility/accname/name-link-mixed-content-expected-blink.txt b/content/test/data/accessibility/accname/name-link-mixed-content-expected-blink.txt
index 41cb85f..80c1b5f 100644
--- a/content/test/data/accessibility/accname/name-link-mixed-content-expected-blink.txt
+++ b/content/test/data/accessibility/accname/name-link-mixed-content-expected-blink.txt
@@ -1,4 +1,4 @@
-# Original expectation was missing a space ("Elithe"), but the spec is not
+# Original expectation was missing a space ("Garaventathe"), but the spec is not
 # clear about this and it seems wrong, the result should match the rendered text
 # more closely. See: https://github.com/w3c/accname/issues/15
-link name='My name is Eli the weird. (QED)' nameFrom=contents
+link name='My name is Garaventa the weird. (QED)' nameFrom=contents
diff --git a/content/test/data/accessibility/html/label-with-presentational-child-expected-blink.txt b/content/test/data/accessibility/html/label-with-presentational-child-expected-blink.txt
index 61d46ea..63b845b 100644
--- a/content/test/data/accessibility/html/label-with-presentational-child-expected-blink.txt
+++ b/content/test/data/accessibility/html/label-with-presentational-child-expected-blink.txt
@@ -1,13 +1,12 @@
 rootWebArea
 ++genericContainer ignored
 ++++genericContainer
-++++++textField name='foo'
+++++++textField name='bar'
 ++++++++genericContainer
 ++++++labelText
-++++++++genericContainer name='foo'
-++++++++++genericContainer name='bar'
-++++++++++++staticText name='baz'
-++++++++++++++inlineTextBox name='baz'
+++++++++genericContainer name='bar'
+++++++++++staticText name='baz'
+++++++++++++inlineTextBox name='baz'
 ++++++lineBreak name='<newline>'
 ++++++++inlineTextBox name='<newline>'
 ++++++textField name='bar'
diff --git a/content/test/data/view_transitions/green.html b/content/test/data/view_transitions/green.html
index c3c3acc..e6505fe 100644
--- a/content/test/data/view_transitions/green.html
+++ b/content/test/data/view_transitions/green.html
@@ -1,6 +1,13 @@
 <!DOCTYPE html>
 <html>
 <head>
+  <!--
+    "width=device-width" tag helps avoiding the ViewTransition screenshot size
+    becomes less than the size of the frame.
+    TODO(https://crbug.com/1495157): Remove this tag if we can get pass the
+    DCHECKs.
+  -->
+  <meta name="viewport" content="width=device-width">
   <meta name="view-transition" content="same-origin">
 </head>
 <body style="background-color:#00FF00"></body>
diff --git a/content/test/data/view_transitions/red_jank_second_pageshow.html b/content/test/data/view_transitions/red_jank_second_pageshow.html
index 0df5509e3..c302f66 100644
--- a/content/test/data/view_transitions/red_jank_second_pageshow.html
+++ b/content/test/data/view_transitions/red_jank_second_pageshow.html
@@ -1,6 +1,13 @@
 <!DOCTYPE html>
 <html>
 <head>
+  <!--
+    "width=device-width" tag helps avoiding the ViewTransition screenshot size
+    becomes less than the size of the frame.
+    TODO(https://crbug.com/1495157): Remove this tag if we can get pass the
+    DCHECKs.
+  -->
+  <meta name="viewport" content="width=device-width">
   <meta name="view-transition" content="same-origin">
   <script>
     let firstPageShow = true;
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
index edfafd92..acb42ee 100644
--- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -410,8 +410,6 @@
 crbug.com/1474611 [ mac nvidia angle-opengl graphite-disabled ] Pixel_WebGLGreenTriangle_NonChromiumImage_NoAA_NoAlpha [ Failure ]
 crbug.com/1477318 [ mac ] Pixel_WebGLPreservedAfterTabSwitch [ RetryOnFailure ]
 
-# GL Crash on Nexus 5X causing flakes
-crbug.com/1489248 [ android android-chromium android-nexus-5x no-clang-coverage ] Pixel_Video_MP4_FourColors_Rot_90 [ RetryOnFailure ]
 
 # Fails almost consistently, but likely to pass when run on its own in the retry.
 crbug.com/1484212 [ win debug nvidia ] Pixel_WebGL2_BlitFramebuffer_Result_Displayed [ RetryOnFailure ]
diff --git a/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt
index 3ca131b..237f9716 100644
--- a/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt
@@ -246,7 +246,6 @@
 
 
 # Canvas capture trace tests on M1 Mac
-crbug.com/1493530 [ angle-metal apple-angle-metal-renderer:-apple-m1 mac ] WebGLCanvasCaptureTraceTest_VideoStreamFromWebGLCanvas_TwoCopy_Accelerated [ RetryOnFailure ]
 crbug.com/1493530 [ angle-metal apple-angle-metal-renderer:-apple-m2 mac ] WebGPUTraceTest_WebGPUCanvasOneCopyCapture_Hidden [ RetryOnFailure ]
 
 #######################################################################
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
index 23a92ae..654ff4a59 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -858,6 +858,8 @@
 crbug.com/1492257 [ chromeos cros-chrome chromeos-board-jacuzzi ] conformance2/glsl3/tricky-loop-conditions.html [ Failure ]
 crbug.com/1492258 [ chromeos cros-chrome chromeos-board-jacuzzi ] conformance2/glsl3/uninitialized-local-global-variables.html [ Failure ]
 crbug.com/1492270 [ chromeos cros-chrome chromeos-board-jacuzzi ] conformance2/reading/read-pixels-pack-parameters.html [ Failure ]
+crbug.com/1499514 [ chromeos cros-chrome chromeos-board-jacuzzi ] conformance/textures/canvas_sub_rectangle/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ RetryOnFailure ]
+crbug.com/1499514 [ chromeos cros-chrome chromeos-board-jacuzzi ] conformance/textures/webgl_canvas/tex-2d-luminance-luminance-unsigned_byte.html [ RetryOnFailure ]
 crbug.com/1499514 [ chromeos cros-chrome chromeos-board-jacuzzi ] conformance2/textures/canvas_sub_rectangle/tex-2d-srgb8-rgb-unsigned_byte.html [ Failure ]
 crbug.com/1499516 [ chromeos cros-chrome chromeos-board-jacuzzi ] conformance2/transform_feedback/transform_feedback.html [ Failure ]
 crbug.com/1499523 [ chromeos cros-chrome chromeos-board-jacuzzi ] deqp/data/gles3/shaders/arrays.html [ Failure ]
@@ -872,6 +874,7 @@
 crbug.com/1499536 [ chromeos cros-chrome chromeos-board-jacuzzi ] deqp/functional/gles3/uniformbuffers/random.html [ Failure ]
 crbug.com/1499536 [ chromeos cros-chrome chromeos-board-jacuzzi ] deqp/functional/gles3/uniformbuffers/single_basic_array.html [ Failure ]
 crbug.com/1499536 [ chromeos cros-chrome chromeos-board-jacuzzi ] deqp/functional/gles3/uniformbuffers/single_basic_type.html [ Failure ]
+crbug.com/1500045 [ chromeos cros-chrome chromeos-board-jacuzzi ] conformance2/rendering/blitframebuffer-r11f-g11f-b10f.html [ RetryOnFailure ]
 
 #####################
 # Lacros failures #
diff --git a/device/bluetooth/floss/floss_adapter_client.cc b/device/bluetooth/floss/floss_adapter_client.cc
index 1d0342b..b98bdd0 100644
--- a/device/bluetooth/floss/floss_adapter_client.cc
+++ b/device/bluetooth/floss/floss_adapter_client.cc
@@ -492,10 +492,15 @@
     return;
   }
 
+  // Block the event in LaCrOS so it won't race with AshChrome. See b/308988818.
+  // TODO(b/274706838): Redesign DBus API so it's only received by the correct
+  // client.
+#if !BUILDFLAG(IS_CHROMEOS_LACROS)
   for (auto& observer : observers_) {
     observer.AdapterSspRequest(
         device, cod, static_cast<BluetoothSspVariant>(variant), passkey);
   }
+#endif  // !BUILDFLAG(IS_CHROMEOS_LACROS)
 
   std::move(response_sender).Run(dbus::Response::FromMethodCall(method_call));
 }
@@ -514,9 +519,14 @@
     return;
   }
 
+  // Block the event in LaCrOS so it won't race with AshChrome. See b/308988818.
+  // TODO(b/274706838): Redesign DBus API so it's only received by the correct
+  // client.
+#if !BUILDFLAG(IS_CHROMEOS_LACROS)
   for (auto& observer : observers_) {
     observer.AdapterPinDisplay(device, pincode);
   }
+#endif  // !BUILDFLAG(IS_CHROMEOS_LACROS)
 
   std::move(response_sender).Run(dbus::Response::FromMethodCall(method_call));
 }
@@ -536,9 +546,14 @@
     return;
   }
 
+  // Block the event in LaCrOS so it won't race with AshChrome. See b/308988818.
+  // TODO(b/274706838): Redesign DBus API so it's only received by the correct
+  // client.
+#if !BUILDFLAG(IS_CHROMEOS_LACROS)
   for (auto& observer : observers_) {
     observer.AdapterPinRequest(device, cod, min_16_digit);
   }
+#endif  // !BUILDFLAG(IS_CHROMEOS_LACROS)
 
   std::move(response_sender).Run(dbus::Response::FromMethodCall(method_call));
 }
diff --git a/device/bluetooth/floss/floss_adapter_client_unittest.cc b/device/bluetooth/floss/floss_adapter_client_unittest.cc
index 07dabee..9a046b5 100644
--- a/device/bluetooth/floss/floss_adapter_client_unittest.cc
+++ b/device/bluetooth/floss/floss_adapter_client_unittest.cc
@@ -709,6 +709,10 @@
   EXPECT_EQ(test_observer.cleared_device_.address, device_id.address);
 }
 
+// Block the event in LaCrOS so it won't race with AshChrome. See b/308988818.
+// TODO(b/274706838): Redesign DBus API so it's only received by the correct
+// client.
+#if !BUILDFLAG(IS_CHROMEOS_LACROS)
 TEST_F(FlossAdapterClientTest, HandlesSsp) {
   TestAdapterObserver test_observer(client_.get());
   client_->Init(bus_.get(), kAdapterInterface, adapter_index_, GetCurrVersion(),
@@ -738,6 +742,7 @@
   EXPECT_EQ(test_observer.variant_, variant);
   EXPECT_EQ(test_observer.passkey_, passkey);
 }
+#endif  // !BUILDFLAG(IS_CHROMEOS_LACROS)
 
 TEST_F(FlossAdapterClientTest, CreateBond) {
   client_->Init(bus_.get(), kAdapterInterface, adapter_index_, GetCurrVersion(),
diff --git a/extensions/browser/api/feedback_private/feedback_private_api_chromeos_unittest.cc b/extensions/browser/api/feedback_private/feedback_private_api_chromeos_unittest.cc
index 517fe625f..0eaa4c1 100644
--- a/extensions/browser/api/feedback_private/feedback_private_api_chromeos_unittest.cc
+++ b/extensions/browser/api/feedback_private/feedback_private_api_chromeos_unittest.cc
@@ -90,20 +90,20 @@
     if (!result_value)
       return testing::AssertionFailure() << "No result";
 
-    ReadLogSourceResult result;
-    if (!ReadLogSourceResult::Populate(*result_value, result)) {
+    auto result = ReadLogSourceResult::FromValue(*result_value);
+    if (!result) {
       return testing::AssertionFailure()
              << "Unable to parse a valid result from " << *result_value;
     }
 
-    if (result.log_lines.size() != 1) {
+    if (result->log_lines.size() != 1) {
       return testing::AssertionFailure()
              << "Expected |log_lines| to contain 1 string, actual number: "
-             << result.log_lines.size();
+             << result->log_lines.size();
     }
 
-    *result_reader_id = result.reader_id;
-    *result_string = result.log_lines[0];
+    *result_reader_id = result->reader_id;
+    *result_string = result->log_lines[0];
 
     return testing::AssertionSuccess();
   }
diff --git a/fuchsia_web/cast_streaming/cast_streaming.cc b/fuchsia_web/cast_streaming/cast_streaming.cc
index 2b82455..57d3247 100644
--- a/fuchsia_web/cast_streaming/cast_streaming.cc
+++ b/fuchsia_web/cast_streaming/cast_streaming.cc
@@ -6,6 +6,7 @@
 
 #include <string>
 
+#include "base/check.h"
 #include "base/fuchsia/file_utils.h"
 #include "base/path_service.h"
 
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_backing.cc b/gpu/command_buffer/service/shared_image/d3d_image_backing.cc
index 5bfa9cb..4910470a 100644
--- a/gpu/command_buffer/service/shared_image/d3d_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/d3d_image_backing.cc
@@ -661,6 +661,15 @@
 #endif  // BUILDFLAG(USE_DAWN)
 }
 
+void D3DImageBacking::UpdateExternalFence(
+    scoped_refptr<gfx::D3DSharedFence> external_fence) {
+  if (!write_fence_) {
+    write_fence_ = std::move(external_fence);
+  }
+
+  // TODO(crbug.com/1236801): Handle cases that write_fence_ exists.
+}
+
 std::unique_ptr<VideoDecodeImageRepresentation>
 D3DImageBacking::ProduceVideoDecode(SharedImageManager* manager,
                                     MemoryTypeTracker* tracker,
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_backing.h b/gpu/command_buffer/service/shared_image/d3d_image_backing.h
index b80b0c33..544c1a6d 100644
--- a/gpu/command_buffer/service/shared_image/d3d_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/d3d_image_backing.h
@@ -97,6 +97,8 @@
       const wgpu::Device& device,
       wgpu::BackendType backend_type,
       std::vector<wgpu::TextureFormat> view_formats) override;
+  void UpdateExternalFence(
+      scoped_refptr<gfx::D3DSharedFence> external_fence) override;
 
   bool BeginAccessD3D11(Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device,
                         bool write_access);
diff --git a/gpu/command_buffer/service/shared_image/shared_image_backing.cc b/gpu/command_buffer/service/shared_image/shared_image_backing.cc
index 0f60f78b..acc664a 100644
--- a/gpu/command_buffer/service/shared_image/shared_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/shared_image_backing.cc
@@ -18,6 +18,10 @@
 #include "gpu/command_buffer/service/shared_image/shared_image_representation.h"
 #include "third_party/skia/include/core/SkColorSpace.h"
 
+#if BUILDFLAG(IS_WIN)
+#include "ui/gfx/win/d3d_shared_fence.h"
+#endif
+
 namespace gpu {
 namespace {
 
@@ -244,6 +248,13 @@
 }
 #endif
 
+#if BUILDFLAG(IS_WIN)
+void SharedImageBacking::UpdateExternalFence(
+    scoped_refptr<gfx::D3DSharedFence> external_fence) {
+  NOTIMPLEMENTED_LOG_ONCE();
+}
+#endif
+
 void SharedImageBacking::UpdateEstimatedSize(size_t estimated_size_bytes) {
   if (estimated_size_bytes == estimated_size_)
     return;
diff --git a/gpu/command_buffer/service/shared_image/shared_image_backing.h b/gpu/command_buffer/service/shared_image/shared_image_backing.h
index 97ebd0b2..cd31d5e 100644
--- a/gpu/command_buffer/service/shared_image/shared_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/shared_image_backing.h
@@ -42,6 +42,7 @@
 }  // namespace base
 
 namespace gfx {
+class D3DSharedFence;
 class GpuFence;
 }  // namespace gfx
 
@@ -300,6 +301,11 @@
   ProduceLegacyOverlay(SharedImageManager* manager, MemoryTypeTracker* tracker);
 #endif
 
+#if BUILDFLAG(IS_WIN)
+  virtual void UpdateExternalFence(
+      scoped_refptr<gfx::D3DSharedFence> external_fence);
+#endif
+
   // Updates the estimated size if memory usage changes after creation.
   void UpdateEstimatedSize(size_t estimated_size_bytes)
       EXCLUSIVE_LOCKS_REQUIRED(lock_);
diff --git a/gpu/command_buffer/service/shared_image/shared_image_factory.cc b/gpu/command_buffer/service/shared_image/shared_image_factory.cc
index e0a5a08..2c84896 100644
--- a/gpu/command_buffer/service/shared_image/shared_image_factory.cc
+++ b/gpu/command_buffer/service/shared_image/shared_image_factory.cc
@@ -889,6 +889,10 @@
   return shared_image_caps;
 }
 
+bool SharedImageFactory::HasSharedImage(const Mailbox& mailbox) const {
+  return shared_images_.contains(mailbox);
+}
+
 void SharedImageFactory::SetGpuExtraInfo(
     const gfx::GpuExtraInfo& gpu_extra_info) {
   gpu_extra_info_ = gpu_extra_info;
diff --git a/gpu/command_buffer/service/shared_image/shared_image_factory.h b/gpu/command_buffer/service/shared_image/shared_image_factory.h
index e9564f4c..f0db175 100644
--- a/gpu/command_buffer/service/shared_image/shared_image_factory.h
+++ b/gpu/command_buffer/service/shared_image/shared_image_factory.h
@@ -153,6 +153,8 @@
 
   gpu::SharedImageCapabilities MakeCapabilities();
 
+  bool HasSharedImage(const Mailbox& mailbox) const;
+
  private:
   bool IsSharedBetweenThreads(uint32_t usage);
 
diff --git a/gpu/command_buffer/service/shared_image/shared_image_manager.cc b/gpu/command_buffer/service/shared_image/shared_image_manager.cc
index 8279b84..0ae7d74 100644
--- a/gpu/command_buffer/service/shared_image/shared_image_manager.cc
+++ b/gpu/command_buffer/service/shared_image/shared_image_manager.cc
@@ -25,6 +25,7 @@
 
 #if BUILDFLAG(IS_WIN)
 #include "gpu/command_buffer/service/dxgi_shared_handle_manager.h"
+#include "ui/gfx/win/d3d_shared_fence.h"
 #include "ui/gl/gl_angle_util_win.h"
 #endif
 
@@ -394,6 +395,24 @@
 }
 #endif
 
+#if BUILDFLAG(IS_WIN)
+void SharedImageManager::UpdateExternalFence(
+    const Mailbox& mailbox,
+    scoped_refptr<gfx::D3DSharedFence> external_fence) {
+  CALLED_ON_VALID_THREAD();
+  AutoLock autolock(this);
+  auto found = images_.find(mailbox);
+  if (found == images_.end()) {
+    LOG(ERROR)
+        << "SharedImageManager::ProduceVideoDecode: Trying to Produce a D3D"
+           "representation from a non-existent mailbox.";
+    return;
+  }
+
+  (*found)->UpdateExternalFence(std::move(external_fence));
+}
+#endif
+
 void SharedImageManager::OnRepresentationDestroyed(
     const Mailbox& mailbox,
     SharedImageRepresentation* representation) {
diff --git a/gpu/command_buffer/service/shared_image/shared_image_manager.h b/gpu/command_buffer/service/shared_image/shared_image_manager.h
index 4b61f93..ad24455 100644
--- a/gpu/command_buffer/service/shared_image/shared_image_manager.h
+++ b/gpu/command_buffer/service/shared_image/shared_image_manager.h
@@ -17,7 +17,9 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_WIN)
-#include <d3d11.h>
+namespace gfx {
+class D3DSharedFence;
+}
 #endif
 
 namespace gpu {
@@ -107,6 +109,11 @@
       MemoryTypeTracker* ref);
 #endif
 
+#if BUILDFLAG(IS_WIN)
+  void UpdateExternalFence(const Mailbox& mailbox,
+                           scoped_refptr<gfx::D3DSharedFence> external_fence);
+#endif
+
   // Called by SharedImageRepresentation in the destructor.
   void OnRepresentationDestroyed(const Mailbox& mailbox,
                                  SharedImageRepresentation* representation);
diff --git a/gpu/ipc/common/gpu_channel.mojom b/gpu/ipc/common/gpu_channel.mojom
index da41fe7..a7030b2 100644
--- a/gpu/ipc/common/gpu_channel.mojom
+++ b/gpu/ipc/common/gpu_channel.mojom
@@ -19,6 +19,7 @@
 import "ui/gfx/mojom/buffer_types.mojom";
 import "ui/gfx/mojom/color_space.mojom";
 import "ui/gfx/mojom/gpu_fence_handle.mojom";
+import "ui/gfx/mojom/native_handle_types.mojom";
 import "ui/gfx/mojom/presentation_feedback.mojom";
 import "ui/gl/mojom/gpu_preference.mojom";
 import "url/mojom/url.mojom";
@@ -482,6 +483,18 @@
   // See PresentSwapChainParams.
   [EnableIf=is_win]
   PresentSwapChainParams present_swap_chain;
+
+  // See RegisterDxgiFenceParams.
+  [EnableIf=is_win]
+  RegisterDxgiFenceParams register_dxgi_fence;
+
+  // See UpdateDxgiFenceParams.
+  [EnableIf=is_win]
+  UpdateDxgiFenceParams update_dxgi_fence;
+
+  // See UnregisterDxgiFenceParams.
+  [EnableIf=is_win]
+  UnregisterDxgiFenceParams unregister_dxgi_fence;
 };
 
 // Asynchronously synchronize the put and get offsets of both processes.
@@ -741,3 +754,37 @@
   // The fence to release once the swap chain is presented.
   uint32 release_id;
 };
+
+[EnableIf=is_win]
+struct RegisterDxgiFenceParams {
+  // Mailbox identifying the shared image backing to register fence.
+  Mailbox mailbox;
+
+  // The DXGIHandleToken to identifying the registered gpu fence handle.
+  // Use this token to update fence after registration.
+  gfx.mojom.DXGIHandleToken dxgi_token;
+
+  // The fence handle to register.
+  gfx.mojom.GpuFenceHandle fence_handle;
+};
+
+[EnableIf=is_win]
+struct UpdateDxgiFenceParams {
+  // Mailbox identifying the shared image backing to update the fence.
+  Mailbox mailbox;
+
+  // The DXGIHandleToken to identifying the fence to update.
+  gfx.mojom.DXGIHandleToken dxgi_token;
+
+  // The fence value to signal.
+  uint64 fence_value;
+};
+
+[EnableIf=is_win]
+struct UnregisterDxgiFenceParams {
+  // Mailbox identifying the shared image backing to clear the fence.
+  Mailbox mailbox;
+
+  // The DXGIHandleToken to identifying the fence needs to be cleared.
+  gfx.mojom.DXGIHandleToken dxgi_token;
+};
diff --git a/gpu/ipc/service/shared_image_stub.cc b/gpu/ipc/service/shared_image_stub.cc
index 86ab9f2..ba12b02 100644
--- a/gpu/ipc/service/shared_image_stub.cc
+++ b/gpu/ipc/service/shared_image_stub.cc
@@ -23,8 +23,14 @@
 #include "gpu/ipc/service/gpu_channel_manager.h"
 #include "gpu/ipc/service/gpu_memory_buffer_factory.h"
 #include "ui/gfx/buffer_format_util.h"
+#include "ui/gfx/gpu_fence_handle.h"
+#include "ui/gfx/gpu_memory_buffer.h"
 #include "ui/gl/gl_context.h"
 
+#if BUILDFLAG(IS_WIN)
+#include "ui/gfx/win/d3d_shared_fence.h"
+#endif
+
 namespace {
 
 constexpr char kInvalidMailboxOnCreateError[] =
@@ -35,8 +41,27 @@
 
 }  // namespace
 
-namespace gpu {
+#if BUILDFLAG(IS_WIN)
+namespace base {
+bool operator<(const scoped_refptr<gfx::D3DSharedFence>& lhs,
+               const scoped_refptr<gfx::D3DSharedFence>& rhs) {
+  return lhs->GetDXGIHandleToken() < rhs->GetDXGIHandleToken();
+}
 
+bool operator<(const gfx::DXGIHandleToken& lhs,
+               const scoped_refptr<gfx::D3DSharedFence>& rhs) {
+  return lhs < rhs->GetDXGIHandleToken();
+}
+
+bool operator<(const scoped_refptr<gfx::D3DSharedFence>& lhs,
+               const gfx::DXGIHandleToken& rhs) {
+  return lhs->GetDXGIHandleToken() < rhs;
+}
+
+}  // namespace base
+#endif
+
+namespace gpu {
 SharedImageStub::SharedImageStub(GpuChannel* channel, int32_t route_id)
     : channel_(channel),
       command_buffer_id_(
@@ -138,6 +163,22 @@
       OnPresentSwapChain(request->get_present_swap_chain()->mailbox,
                          request->get_present_swap_chain()->release_id);
       break;
+    case mojom::DeferredSharedImageRequest::Tag::kRegisterDxgiFence: {
+      auto& reg = *request->get_register_dxgi_fence();
+      OnRegisterDxgiFence(reg.mailbox, reg.dxgi_token,
+                          std::move(reg.fence_handle));
+      break;
+    }
+    case mojom::DeferredSharedImageRequest::Tag::kUpdateDxgiFence: {
+      auto& update = *request->get_update_dxgi_fence();
+      OnUpdateDxgiFence(update.mailbox, update.dxgi_token, update.fence_value);
+      break;
+    }
+    case mojom::DeferredSharedImageRequest::Tag::kUnregisterDxgiFence: {
+      auto& unregister = *request->get_unregister_dxgi_fence();
+      OnUnregisterDxgiFence(unregister.mailbox, unregister.dxgi_token);
+      break;
+    }
 #endif  // BUILDFLAG(IS_WIN)
   }
 }
@@ -447,6 +488,10 @@
     OnError();
     return;
   }
+
+#if BUILDFLAG(IS_WIN)
+  registered_dxgi_fences_.erase(mailbox);
+#endif
 }
 
 #if BUILDFLAG(IS_WIN)
@@ -523,6 +568,103 @@
 
   sync_point_client_state_->ReleaseFenceSync(release_id);
 }
+
+void SharedImageStub::OnRegisterDxgiFence(const Mailbox& mailbox,
+                                          gfx::DXGIHandleToken dxgi_token,
+                                          gfx::GpuFenceHandle fence_handle) {
+  if (!mailbox.IsSharedImage()) {
+    LOG(ERROR)
+        << "SharedImageStub: Trying to register a fence handle in SharedImage "
+           "with a non-SharedImage mailbox.";
+    OnError();
+    return;
+  }
+
+  if (!factory_->HasSharedImage(mailbox)) {
+    LOG(ERROR) << "SharedImageStub: Trying to register a fence handle to a "
+                  "invalid SharedImage.";
+    OnError();
+    return;
+  }
+
+  auto& mailbox_fences = registered_dxgi_fences_[mailbox];
+  auto it = mailbox_fences.find(dxgi_token);
+  if (it != mailbox_fences.end()) {
+    LOG(ERROR) << "SharedImageStub: Trying to register the same fence handle "
+                  "multiple times in SharedImage.";
+    OnError();
+    return;
+  }
+
+  mailbox_fences.emplace_hint(mailbox_fences.begin(),
+                              gfx::D3DSharedFence::CreateFromScopedHandle(
+                                  fence_handle.Release(), dxgi_token));
+}
+
+void SharedImageStub::OnUpdateDxgiFence(const Mailbox& mailbox,
+                                        gfx::DXGIHandleToken dxgi_token,
+                                        uint64_t fence_value) {
+  if (!mailbox.IsSharedImage()) {
+    LOG(ERROR)
+        << "SharedImageStub: Trying to register a fence handle in SharedImage "
+           "with a non-SharedImage mailbox.";
+    OnError();
+    return;
+  }
+
+  if (!factory_->HasSharedImage(mailbox)) {
+    LOG(ERROR) << "SharedImageStub: Trying to register a fence handle to a "
+                  "invalid SharedImage.";
+    OnError();
+    return;
+  }
+
+  auto mailbox_fences_it = registered_dxgi_fences_.find(mailbox);
+  if (mailbox_fences_it == registered_dxgi_fences_.end()) {
+    LOG(ERROR) << "Trying to update a fence on shared image with no registered "
+                  "fences.";
+    OnError();
+    return;
+  }
+
+  auto& mailbox_fences = mailbox_fences_it->second;
+  auto fence_it = mailbox_fences.find(dxgi_token);
+  if (fence_it == mailbox_fences.end()) {
+    LOG(ERROR) << "Trying to update a fence that has not been registered with "
+                  "shared image.";
+    OnError();
+    return;
+  }
+
+  scoped_refptr<gfx::D3DSharedFence> fence = *fence_it;
+  fence->Update(fence_value);
+
+  channel_->gpu_channel_manager()->shared_image_manager()->UpdateExternalFence(
+      mailbox, std::move(fence));
+}
+
+void SharedImageStub::OnUnregisterDxgiFence(const Mailbox& mailbox,
+                                            gfx::DXGIHandleToken dxgi_token) {
+  auto mailbox_fences_it = registered_dxgi_fences_.find(mailbox);
+  if (mailbox_fences_it == registered_dxgi_fences_.end()) {
+    LOG(ERROR) << "Trying to unregister a fence on shared image with no "
+                  "registered fences.";
+    OnError();
+    return;
+  }
+
+  auto& mailbox_fences = mailbox_fences_it->second;
+  auto fence_it = mailbox_fences.find(dxgi_token);
+  if (fence_it == mailbox_fences.end()) {
+    LOG(ERROR) << "Trying to unregister a fence that has not been registered "
+                  "with shared image.";
+    OnError();
+    return;
+  }
+
+  mailbox_fences.erase(fence_it);
+}
+
 #endif  // BUILDFLAG(IS_WIN)
 
 #if BUILDFLAG(IS_FUCHSIA)
diff --git a/gpu/ipc/service/shared_image_stub.h b/gpu/ipc/service/shared_image_stub.h
index eff0c2d0..b934c4c 100644
--- a/gpu/ipc/service/shared_image_stub.h
+++ b/gpu/ipc/service/shared_image_stub.h
@@ -16,6 +16,14 @@
 #include "gpu/ipc/service/gpu_ipc_service_export.h"
 #include "ui/gfx/gpu_extra_info.h"
 
+namespace gfx {
+#if BUILDFLAG(IS_WIN)
+class D3DSharedFence;
+#endif
+
+struct GpuFenceHandle;
+}  // namespace gfx
+
 namespace gpu {
 class SharedContextState;
 struct Mailbox;
@@ -111,6 +119,14 @@
   void OnCopyToGpuMemoryBuffer(const Mailbox& mailbox, uint32_t release_id);
   void OnCreateSwapChain(mojom::CreateSwapChainParamsPtr params);
   void OnPresentSwapChain(const Mailbox& mailbox, uint32_t release_id);
+  void OnRegisterDxgiFence(const Mailbox& mailbox,
+                           gfx::DXGIHandleToken dxgi_token,
+                           gfx::GpuFenceHandle fence_handle);
+  void OnUpdateDxgiFence(const Mailbox& mailbox,
+                         gfx::DXGIHandleToken dxgi_token,
+                         uint64_t fence_value);
+  void OnUnregisterDxgiFence(const Mailbox& mailbox,
+                             gfx::DXGIHandleToken dxgi_token);
 #endif  // BUILDFLAG(IS_WIN)
 
   bool MakeContextCurrent(bool needs_gl = false);
@@ -139,6 +155,13 @@
   base::ReadOnlySharedMemoryRegion upload_memory_;
   base::ReadOnlySharedMemoryMapping upload_memory_mapping_;
 
+#if BUILDFLAG(IS_WIN)
+  // Fences held by external processes. Registered and signaled from ipc
+  // channel. Using DXGIHandleToken to identify the fence.
+  base::flat_map<Mailbox, base::flat_set<scoped_refptr<gfx::D3DSharedFence>>>
+      registered_dxgi_fences_;
+#endif
+
   base::WeakPtrFactory<SharedImageStub> weak_factory_{this};
 };
 
diff --git a/headless/public/util/error_reporter.h b/headless/public/util/error_reporter.h
index 54b25081..f764ad6 100644
--- a/headless/public/util/error_reporter.h
+++ b/headless/public/util/error_reporter.h
@@ -8,6 +8,7 @@
 #include <string>
 #include <vector>
 
+#include "base/dcheck_is_on.h"
 #include "base/strings/string_piece.h"
 #include "headless/public/headless_export.h"
 
diff --git a/infra/config/OWNERS b/infra/config/OWNERS
index cf76c13..936c902c 100644
--- a/infra/config/OWNERS
+++ b/infra/config/OWNERS
@@ -27,6 +27,3 @@
 per-file subprojects/chromium/ci/chromium.fuchsia.fyi.star=file://build/fuchsia/OWNERS
 per-file subprojects/chromium/ci/chromium.fuchsia.star=file://build/fuchsia/OWNERS
 per-file subprojects/chromium/try/tryserver.chromium.fuchsia.star=file://build/fuchsia/OWNERS
-
-# Chrome Browser Build owners
-per-file subprojects/chromium/ci/chromium.build.star=file://infra/config/groups/chrome-build/OWNERS
diff --git a/infra/config/generated/builders/ci/chromeos-jacuzzi-rel-skylab-fyi/properties.json b/infra/config/generated/builders/ci/chromeos-jacuzzi-rel-skylab-fyi/properties.json
new file mode 100644
index 0000000..6569126
--- /dev/null
+++ b/infra/config/generated/builders/ci/chromeos-jacuzzi-rel-skylab-fyi/properties.json
@@ -0,0 +1,74 @@
+{
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "chromeos-jacuzzi-rel-skylab-fyi",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "builder_group": "chromium.fyi",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_arch": "arm",
+                "target_bits": 32,
+                "target_cros_boards": [
+                  "jacuzzi",
+                  "arm-generic"
+                ],
+                "target_platform": "chromeos"
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "chromeos",
+                  "checkout_lacros_sdk"
+                ],
+                "config": "chromium"
+              },
+              "skylab_upload_location": {
+                "gs_bucket": "chrome-test-builds",
+                "gs_extra": "ash"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "chromeos-jacuzzi-rel-skylab-fyi",
+          "project": "chromium"
+        }
+      ],
+      "mirroring_builder_group_and_names": [
+        {
+          "builder": "chromeos-jacuzzi-rel-skylab",
+          "group": "tryserver.chromium.chromiumos"
+        }
+      ]
+    }
+  },
+  "$build/reclient": {
+    "instance": "rbe-chromium-trusted",
+    "jobs": 250,
+    "metrics_project": "chromium-reclient-metrics",
+    "scandeps_server": true
+  },
+  "$recipe_engine/resultdb/test_presentation": {
+    "column_keys": [],
+    "grouping_keys": [
+      "status",
+      "v.test_suite"
+    ]
+  },
+  "builder_group": "chromium.fyi",
+  "recipe": "chromium"
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/chromeos-jacuzzi-rel-skylab-fyi/shadow-properties.json b/infra/config/generated/builders/ci/chromeos-jacuzzi-rel-skylab-fyi/shadow-properties.json
new file mode 100644
index 0000000..999510c
--- /dev/null
+++ b/infra/config/generated/builders/ci/chromeos-jacuzzi-rel-skylab-fyi/shadow-properties.json
@@ -0,0 +1,8 @@
+{
+  "$build/reclient": {
+    "instance": "rbe-chromium-untrusted",
+    "jobs": 250,
+    "metrics_project": "chromium-reclient-metrics",
+    "scandeps_server": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/chromeos-jacuzzi-rel-skylab/properties.json b/infra/config/generated/builders/try/chromeos-jacuzzi-rel-skylab/properties.json
new file mode 100644
index 0000000..6c3ff1e6
--- /dev/null
+++ b/infra/config/generated/builders/try/chromeos-jacuzzi-rel-skylab/properties.json
@@ -0,0 +1,68 @@
+{
+  "$build/chromium_tests_builder_config": {
+    "builder_config": {
+      "builder_db": {
+        "entries": [
+          {
+            "builder_id": {
+              "bucket": "ci",
+              "builder": "chromeos-jacuzzi-rel-skylab-fyi",
+              "project": "chromium"
+            },
+            "builder_spec": {
+              "builder_group": "chromium.fyi",
+              "execution_mode": "COMPILE_AND_TEST",
+              "legacy_chromium_config": {
+                "apply_configs": [
+                  "mb"
+                ],
+                "build_config": "Release",
+                "config": "chromium",
+                "target_arch": "arm",
+                "target_bits": 32,
+                "target_cros_boards": [
+                  "jacuzzi",
+                  "arm-generic"
+                ],
+                "target_platform": "chromeos"
+              },
+              "legacy_gclient_config": {
+                "apply_configs": [
+                  "chromeos",
+                  "checkout_lacros_sdk"
+                ],
+                "config": "chromium"
+              },
+              "skylab_upload_location": {
+                "gs_bucket": "chrome-test-builds",
+                "gs_extra": "ash"
+              }
+            }
+          }
+        ]
+      },
+      "builder_ids": [
+        {
+          "bucket": "ci",
+          "builder": "chromeos-jacuzzi-rel-skylab-fyi",
+          "project": "chromium"
+        }
+      ]
+    }
+  },
+  "$build/reclient": {
+    "instance": "rbe-chromium-untrusted",
+    "jobs": 150,
+    "metrics_project": "chromium-reclient-metrics",
+    "scandeps_server": true
+  },
+  "$recipe_engine/resultdb/test_presentation": {
+    "column_keys": [],
+    "grouping_keys": [
+      "status",
+      "v.test_suite"
+    ]
+  },
+  "builder_group": "tryserver.chromium.chromiumos",
+  "recipe": "chromium_trybot"
+}
\ No newline at end of file
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg
index 1c7b3a3a..cf75f94 100644
--- a/infra/config/generated/luci/commit-queue.cfg
+++ b/infra/config/generated/luci/commit-queue.cfg
@@ -1708,6 +1708,10 @@
         includable_only: true
       }
       builders {
+        name: "chromium/try/chromeos-jacuzzi-rel-skylab"
+        includable_only: true
+      }
+      builders {
         name: "chromium/try/chromeos-js-code-coverage"
         includable_only: true
       }
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index 2188046..767b6c0 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -5,6 +5,1776 @@
 #   https://config.luci.app/schemas/projects:buildbucket.cfg
 
 buckets {
+  name: "build"
+  swarming {
+    builders {
+      name: "android-build-perf-developer"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builder:android-build-perf-developer"
+      dimensions: "os:Ubuntu-22.04"
+      dimensions: "pool:luci.chromium.ci"
+      exe {
+        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
+        cipd_version: "refs/heads/main"
+        cmd: "luciexe"
+      }
+      properties:
+        '{'
+        '  "$build/chromium_tests_builder_config": {'
+        '    "builder_config": {'
+        '      "builder_db": {'
+        '        "entries": ['
+        '          {'
+        '            "builder_id": {'
+        '              "bucket": "build",'
+        '              "builder": "android-build-perf-developer",'
+        '              "project": "chromium"'
+        '            },'
+        '            "builder_spec": {'
+        '              "builder_group": "chromium.build",'
+        '              "execution_mode": "COMPILE_AND_TEST",'
+        '              "legacy_android_config": {'
+        '                "config": "main_builder"'
+        '              },'
+        '              "legacy_chromium_config": {'
+        '                "apply_configs": ['
+        '                  "mb"'
+        '                ],'
+        '                "build_config": "Debug",'
+        '                "config": "android",'
+        '                "target_bits": 64,'
+        '                "target_platform": "android"'
+        '              },'
+        '              "legacy_gclient_config": {'
+        '                "apply_configs": ['
+        '                  "android",'
+        '                  "siso_latest"'
+        '                ],'
+        '                "config": "chromium"'
+        '              }'
+        '            }'
+        '          }'
+        '        ]'
+        '      },'
+        '      "builder_ids": ['
+        '        {'
+        '          "bucket": "build",'
+        '          "builder": "android-build-perf-developer",'
+        '          "project": "chromium"'
+        '        }'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$build/reclient": {'
+        '    "instance": "rbe-chromium-untrusted",'
+        '    "jobs": 5120,'
+        '    "metrics_project": "chromium-reclient-metrics",'
+        '    "scandeps_server": true'
+        '  },'
+        '  "$build/siso": {'
+        '    "configs": [],'
+        '    "enable_cloud_profiler": true,'
+        '    "enable_cloud_trace": true,'
+        '    "experiments": [],'
+        '    "project": "rbe-chromium-untrusted"'
+        '  },'
+        '  "$recipe_engine/resultdb/test_presentation": {'
+        '    "column_keys": [],'
+        '    "grouping_keys": ['
+        '      "status",'
+        '      "v.test_suite"'
+        '    ]'
+        '  },'
+        '  "builder_group": "chromium.build",'
+        '  "recipe": "chrome_build/build_perf_developer"'
+        '}'
+      priority: 35
+      execution_timeout_secs: 36000
+      build_numbers: YES
+      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+      description_html: "This builder measures build performance for Android developer builds, by simulating developer build scenarios on a high spec bot.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
+      contact_team_email: "chrome-build-team@google.com"
+    }
+    builders {
+      name: "build-perf-android"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builder:build-perf-android"
+      dimensions: "os:Ubuntu-22.04"
+      dimensions: "pool:luci.chromium.ci"
+      exe {
+        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
+        cipd_version: "refs/heads/main"
+        cmd: "luciexe"
+      }
+      properties:
+        '{'
+        '  "$build/chromium_tests_builder_config": {'
+        '    "builder_config": {'
+        '      "builder_db": {'
+        '        "entries": ['
+        '          {'
+        '            "builder_id": {'
+        '              "bucket": "build",'
+        '              "builder": "build-perf-android",'
+        '              "project": "chromium"'
+        '            },'
+        '            "builder_spec": {'
+        '              "builder_group": "chromium.build",'
+        '              "execution_mode": "COMPILE_AND_TEST",'
+        '              "legacy_android_config": {'
+        '                "config": "main_builder"'
+        '              },'
+        '              "legacy_chromium_config": {'
+        '                "apply_configs": ['
+        '                  "mb"'
+        '                ],'
+        '                "build_config": "Release",'
+        '                "config": "android",'
+        '                "target_bits": 64,'
+        '                "target_platform": "android"'
+        '              },'
+        '              "legacy_gclient_config": {'
+        '                "apply_configs": ['
+        '                  "android"'
+        '                ],'
+        '                "config": "chromium"'
+        '              }'
+        '            }'
+        '          }'
+        '        ]'
+        '      },'
+        '      "builder_ids": ['
+        '        {'
+        '          "bucket": "build",'
+        '          "builder": "build-perf-android",'
+        '          "project": "chromium"'
+        '        }'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$build/code_coverage": {'
+        '    "use_clang_coverage": true'
+        '  },'
+        '  "$build/reclient": {'
+        '    "instance": "rbe-chromium-untrusted",'
+        '    "jobs": 500,'
+        '    "metrics_project": "chromium-reclient-metrics",'
+        '    "scandeps_server": true'
+        '  },'
+        '  "$build/siso": {'
+        '    "configs": ['
+        '      "builder"'
+        '    ],'
+        '    "enable_cloud_profiler": true,'
+        '    "enable_cloud_trace": true,'
+        '    "experiments": [],'
+        '    "project": "rbe-chromium-untrusted"'
+        '  },'
+        '  "$recipe_engine/resultdb/test_presentation": {'
+        '    "column_keys": [],'
+        '    "grouping_keys": ['
+        '      "status",'
+        '      "v.test_suite"'
+        '    ]'
+        '  },'
+        '  "builder_group": "chromium.build",'
+        '  "recipe": "chrome_build/build_perf"'
+        '}'
+      priority: 35
+      execution_timeout_secs: 36000
+      build_numbers: YES
+      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+      description_html: "This builder measures Android build performance with and without remote caches.<br/>The build configs and the bot specs should be in sync with <a href=\"https://ci.chromium.org/p/chromium/builders/try/android-arm64-rel-compilator\">android-arm64-rel-compilator</a>.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
+      contact_team_email: "chrome-build-team@google.com"
+    }
+    builders {
+      name: "build-perf-android-siso"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builder:build-perf-android-siso"
+      dimensions: "os:Ubuntu-22.04"
+      dimensions: "pool:luci.chromium.ci"
+      exe {
+        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
+        cipd_version: "refs/heads/main"
+        cmd: "luciexe"
+      }
+      properties:
+        '{'
+        '  "$build/chromium_tests_builder_config": {'
+        '    "builder_config": {'
+        '      "builder_db": {'
+        '        "entries": ['
+        '          {'
+        '            "builder_id": {'
+        '              "bucket": "build",'
+        '              "builder": "build-perf-android-siso",'
+        '              "project": "chromium"'
+        '            },'
+        '            "builder_spec": {'
+        '              "builder_group": "chromium.build",'
+        '              "execution_mode": "COMPILE_AND_TEST",'
+        '              "legacy_android_config": {'
+        '                "config": "main_builder"'
+        '              },'
+        '              "legacy_chromium_config": {'
+        '                "apply_configs": ['
+        '                  "mb"'
+        '                ],'
+        '                "build_config": "Release",'
+        '                "config": "android",'
+        '                "target_bits": 64,'
+        '                "target_platform": "android"'
+        '              },'
+        '              "legacy_gclient_config": {'
+        '                "apply_configs": ['
+        '                  "android",'
+        '                  "siso_latest"'
+        '                ],'
+        '                "config": "chromium"'
+        '              }'
+        '            }'
+        '          }'
+        '        ]'
+        '      },'
+        '      "builder_ids": ['
+        '        {'
+        '          "bucket": "build",'
+        '          "builder": "build-perf-android-siso",'
+        '          "project": "chromium"'
+        '        }'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$build/code_coverage": {'
+        '    "use_clang_coverage": true'
+        '  },'
+        '  "$build/reclient": {'
+        '    "instance": "rbe-chromium-untrusted",'
+        '    "jobs": 500,'
+        '    "metrics_project": "chromium-reclient-metrics",'
+        '    "scandeps_server": true'
+        '  },'
+        '  "$build/siso": {'
+        '    "configs": ['
+        '      "builder"'
+        '    ],'
+        '    "enable_cloud_profiler": true,'
+        '    "enable_cloud_trace": true,'
+        '    "experiments": [],'
+        '    "project": "rbe-chromium-untrusted"'
+        '  },'
+        '  "$recipe_engine/resultdb/test_presentation": {'
+        '    "column_keys": [],'
+        '    "grouping_keys": ['
+        '      "status",'
+        '      "v.test_suite"'
+        '    ]'
+        '  },'
+        '  "builder_group": "chromium.build",'
+        '  "recipe": "chrome_build/build_perf_siso"'
+        '}'
+      priority: 35
+      execution_timeout_secs: 36000
+      build_numbers: YES
+      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+      description_html: "This builder measures Android build performance with Siso<br/>The build configs and the bot specs should be in sync with <a href=\"https://ci.chromium.org/p/chromium/builders/try/android-arm64-rel-compilator\">android-arm64-rel-compilator</a>.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
+      contact_team_email: "chrome-build-team@google.com"
+    }
+    builders {
+      name: "build-perf-linux"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builder:build-perf-linux"
+      dimensions: "os:Ubuntu-22.04"
+      dimensions: "pool:luci.chromium.ci"
+      exe {
+        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
+        cipd_version: "refs/heads/main"
+        cmd: "luciexe"
+      }
+      properties:
+        '{'
+        '  "$build/chromium_tests_builder_config": {'
+        '    "builder_config": {'
+        '      "builder_db": {'
+        '        "entries": ['
+        '          {'
+        '            "builder_id": {'
+        '              "bucket": "build",'
+        '              "builder": "build-perf-linux",'
+        '              "project": "chromium"'
+        '            },'
+        '            "builder_spec": {'
+        '              "builder_group": "chromium.build",'
+        '              "execution_mode": "COMPILE_AND_TEST",'
+        '              "legacy_chromium_config": {'
+        '                "apply_configs": ['
+        '                  "mb"'
+        '                ],'
+        '                "config": "chromium"'
+        '              },'
+        '              "legacy_gclient_config": {'
+        '                "config": "chromium"'
+        '              }'
+        '            }'
+        '          }'
+        '        ]'
+        '      },'
+        '      "builder_ids": ['
+        '        {'
+        '          "bucket": "build",'
+        '          "builder": "build-perf-linux",'
+        '          "project": "chromium"'
+        '        }'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$build/code_coverage": {'
+        '    "use_clang_coverage": true'
+        '  },'
+        '  "$build/reclient": {'
+        '    "instance": "rbe-chromium-untrusted",'
+        '    "jobs": 500,'
+        '    "metrics_project": "chromium-reclient-metrics",'
+        '    "scandeps_server": true'
+        '  },'
+        '  "$build/siso": {'
+        '    "configs": ['
+        '      "builder"'
+        '    ],'
+        '    "enable_cloud_profiler": true,'
+        '    "enable_cloud_trace": true,'
+        '    "experiments": [],'
+        '    "project": "rbe-chromium-untrusted"'
+        '  },'
+        '  "$recipe_engine/resultdb/test_presentation": {'
+        '    "column_keys": [],'
+        '    "grouping_keys": ['
+        '      "status",'
+        '      "v.test_suite"'
+        '    ]'
+        '  },'
+        '  "builder_group": "chromium.build",'
+        '  "recipe": "chrome_build/build_perf"'
+        '}'
+      priority: 35
+      execution_timeout_secs: 36000
+      build_numbers: YES
+      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+      description_html: "This builder measures Linux build performance with and without remote caches.<br/>The build configs and the bot specs should be in sync with <a href=\"https://ci.chromium.org/p/chromium/builders/try/linux-rel-compilator\">linux-rel-compilator</a>.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
+      contact_team_email: "chrome-build-team@google.com"
+    }
+    builders {
+      name: "build-perf-linux-siso"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builder:build-perf-linux-siso"
+      dimensions: "os:Ubuntu-22.04"
+      dimensions: "pool:luci.chromium.ci"
+      exe {
+        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
+        cipd_version: "refs/heads/main"
+        cmd: "luciexe"
+      }
+      properties:
+        '{'
+        '  "$build/chromium_tests_builder_config": {'
+        '    "builder_config": {'
+        '      "builder_db": {'
+        '        "entries": ['
+        '          {'
+        '            "builder_id": {'
+        '              "bucket": "build",'
+        '              "builder": "build-perf-linux-siso",'
+        '              "project": "chromium"'
+        '            },'
+        '            "builder_spec": {'
+        '              "builder_group": "chromium.build",'
+        '              "execution_mode": "COMPILE_AND_TEST",'
+        '              "legacy_chromium_config": {'
+        '                "apply_configs": ['
+        '                  "mb"'
+        '                ],'
+        '                "config": "chromium"'
+        '              },'
+        '              "legacy_gclient_config": {'
+        '                "apply_configs": ['
+        '                  "siso_latest"'
+        '                ],'
+        '                "config": "chromium"'
+        '              }'
+        '            }'
+        '          }'
+        '        ]'
+        '      },'
+        '      "builder_ids": ['
+        '        {'
+        '          "bucket": "build",'
+        '          "builder": "build-perf-linux-siso",'
+        '          "project": "chromium"'
+        '        }'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$build/code_coverage": {'
+        '    "use_clang_coverage": true'
+        '  },'
+        '  "$build/reclient": {'
+        '    "instance": "rbe-chromium-untrusted",'
+        '    "jobs": 500,'
+        '    "metrics_project": "chromium-reclient-metrics",'
+        '    "scandeps_server": true'
+        '  },'
+        '  "$build/siso": {'
+        '    "configs": ['
+        '      "builder"'
+        '    ],'
+        '    "enable_cloud_profiler": true,'
+        '    "enable_cloud_trace": true,'
+        '    "experiments": [],'
+        '    "project": "rbe-chromium-untrusted"'
+        '  },'
+        '  "$recipe_engine/resultdb/test_presentation": {'
+        '    "column_keys": [],'
+        '    "grouping_keys": ['
+        '      "status",'
+        '      "v.test_suite"'
+        '    ]'
+        '  },'
+        '  "builder_group": "chromium.build",'
+        '  "recipe": "chrome_build/build_perf_siso"'
+        '}'
+      priority: 35
+      execution_timeout_secs: 36000
+      build_numbers: YES
+      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+      description_html: "This builder measures Linux build performance with Siso.<br/>The build configs and the bot specs should be in sync with <a href=\"https://ci.chromium.org/p/chromium/builders/try/linux-rel-compilator\">linux-rel-compilator</a>.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
+      contact_team_email: "chrome-build-team@google.com"
+    }
+    builders {
+      name: "build-perf-windows"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builder:build-perf-windows"
+      dimensions: "os:Windows-10"
+      dimensions: "pool:luci.chromium.ci"
+      exe {
+        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
+        cipd_version: "refs/heads/main"
+        cmd: "luciexe"
+      }
+      properties:
+        '{'
+        '  "$build/chromium_tests_builder_config": {'
+        '    "builder_config": {'
+        '      "builder_db": {'
+        '        "entries": ['
+        '          {'
+        '            "builder_id": {'
+        '              "bucket": "build",'
+        '              "builder": "build-perf-windows",'
+        '              "project": "chromium"'
+        '            },'
+        '            "builder_spec": {'
+        '              "builder_group": "chromium.build",'
+        '              "execution_mode": "COMPILE_AND_TEST",'
+        '              "legacy_chromium_config": {'
+        '                "apply_configs": ['
+        '                  "mb"'
+        '                ],'
+        '                "config": "chromium"'
+        '              },'
+        '              "legacy_gclient_config": {'
+        '                "config": "chromium"'
+        '              }'
+        '            }'
+        '          }'
+        '        ]'
+        '      },'
+        '      "builder_ids": ['
+        '        {'
+        '          "bucket": "build",'
+        '          "builder": "build-perf-windows",'
+        '          "project": "chromium"'
+        '        }'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$build/code_coverage": {'
+        '    "use_clang_coverage": true'
+        '  },'
+        '  "$build/reclient": {'
+        '    "instance": "rbe-chromium-untrusted",'
+        '    "jobs": 500,'
+        '    "metrics_project": "chromium-reclient-metrics",'
+        '    "scandeps_server": true'
+        '  },'
+        '  "$build/siso": {'
+        '    "configs": ['
+        '      "builder"'
+        '    ],'
+        '    "enable_cloud_profiler": true,'
+        '    "enable_cloud_trace": true,'
+        '    "experiments": [],'
+        '    "project": "rbe-chromium-untrusted"'
+        '  },'
+        '  "$recipe_engine/resultdb/test_presentation": {'
+        '    "column_keys": [],'
+        '    "grouping_keys": ['
+        '      "status",'
+        '      "v.test_suite"'
+        '    ]'
+        '  },'
+        '  "builder_group": "chromium.build",'
+        '  "recipe": "chrome_build/build_perf"'
+        '}'
+      priority: 35
+      execution_timeout_secs: 36000
+      build_numbers: YES
+      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+      description_html: "This builder measures Windows build performance with and without remote caches.<br/>The build configs and the bot specs should be in sync with <a href=\"https://ci.chromium.org/p/chromium/builders/try/win-rel-compilator\">win-rel-compilator</a>.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
+      contact_team_email: "chrome-build-team@google.com"
+    }
+    builders {
+      name: "build-perf-windows-siso"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builder:build-perf-windows-siso"
+      dimensions: "os:Windows-10"
+      dimensions: "pool:luci.chromium.ci"
+      exe {
+        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
+        cipd_version: "refs/heads/main"
+        cmd: "luciexe"
+      }
+      properties:
+        '{'
+        '  "$build/chromium_tests_builder_config": {'
+        '    "builder_config": {'
+        '      "builder_db": {'
+        '        "entries": ['
+        '          {'
+        '            "builder_id": {'
+        '              "bucket": "build",'
+        '              "builder": "build-perf-windows-siso",'
+        '              "project": "chromium"'
+        '            },'
+        '            "builder_spec": {'
+        '              "builder_group": "chromium.build",'
+        '              "execution_mode": "COMPILE_AND_TEST",'
+        '              "legacy_chromium_config": {'
+        '                "apply_configs": ['
+        '                  "mb"'
+        '                ],'
+        '                "config": "chromium"'
+        '              },'
+        '              "legacy_gclient_config": {'
+        '                "apply_configs": ['
+        '                  "siso_latest"'
+        '                ],'
+        '                "config": "chromium"'
+        '              }'
+        '            }'
+        '          }'
+        '        ]'
+        '      },'
+        '      "builder_ids": ['
+        '        {'
+        '          "bucket": "build",'
+        '          "builder": "build-perf-windows-siso",'
+        '          "project": "chromium"'
+        '        }'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$build/code_coverage": {'
+        '    "use_clang_coverage": true'
+        '  },'
+        '  "$build/reclient": {'
+        '    "instance": "rbe-chromium-untrusted",'
+        '    "jobs": 500,'
+        '    "metrics_project": "chromium-reclient-metrics",'
+        '    "scandeps_server": true'
+        '  },'
+        '  "$build/siso": {'
+        '    "configs": ['
+        '      "builder"'
+        '    ],'
+        '    "enable_cloud_profiler": true,'
+        '    "enable_cloud_trace": true,'
+        '    "experiments": [],'
+        '    "project": "rbe-chromium-untrusted"'
+        '  },'
+        '  "$recipe_engine/resultdb/test_presentation": {'
+        '    "column_keys": [],'
+        '    "grouping_keys": ['
+        '      "status",'
+        '      "v.test_suite"'
+        '    ]'
+        '  },'
+        '  "builder_group": "chromium.build",'
+        '  "recipe": "chrome_build/build_perf_siso"'
+        '}'
+      priority: 35
+      execution_timeout_secs: 36000
+      build_numbers: YES
+      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+      description_html: "This builder measures Windows build performance with Siso.<br/>The build configs and the bot specs should be in sync with <a href=\"https://ci.chromium.org/p/chromium/builders/try/win-rel-compilator\">win-rel-compilator</a>.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
+      contact_team_email: "chrome-build-team@google.com"
+    }
+    builders {
+      name: "linux-build-perf-developer"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builder:linux-build-perf-developer"
+      dimensions: "os:Ubuntu-22.04"
+      dimensions: "pool:luci.chromium.ci"
+      exe {
+        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
+        cipd_version: "refs/heads/main"
+        cmd: "luciexe"
+      }
+      properties:
+        '{'
+        '  "$build/chromium_tests_builder_config": {'
+        '    "builder_config": {'
+        '      "builder_db": {'
+        '        "entries": ['
+        '          {'
+        '            "builder_id": {'
+        '              "bucket": "build",'
+        '              "builder": "linux-build-perf-developer",'
+        '              "project": "chromium"'
+        '            },'
+        '            "builder_spec": {'
+        '              "builder_group": "chromium.build",'
+        '              "execution_mode": "COMPILE_AND_TEST",'
+        '              "legacy_chromium_config": {'
+        '                "apply_configs": ['
+        '                  "mb"'
+        '                ],'
+        '                "config": "chromium"'
+        '              },'
+        '              "legacy_gclient_config": {'
+        '                "apply_configs": ['
+        '                  "siso_latest"'
+        '                ],'
+        '                "config": "chromium"'
+        '              }'
+        '            }'
+        '          }'
+        '        ]'
+        '      },'
+        '      "builder_ids": ['
+        '        {'
+        '          "bucket": "build",'
+        '          "builder": "linux-build-perf-developer",'
+        '          "project": "chromium"'
+        '        }'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$build/reclient": {'
+        '    "instance": "rbe-chromium-untrusted",'
+        '    "jobs": 5120,'
+        '    "metrics_project": "chromium-reclient-metrics",'
+        '    "scandeps_server": true'
+        '  },'
+        '  "$build/siso": {'
+        '    "configs": [],'
+        '    "enable_cloud_profiler": true,'
+        '    "enable_cloud_trace": true,'
+        '    "experiments": [],'
+        '    "project": "rbe-chromium-untrusted"'
+        '  },'
+        '  "$recipe_engine/resultdb/test_presentation": {'
+        '    "column_keys": [],'
+        '    "grouping_keys": ['
+        '      "status",'
+        '      "v.test_suite"'
+        '    ]'
+        '  },'
+        '  "builder_group": "chromium.build",'
+        '  "recipe": "chrome_build/build_perf_developer"'
+        '}'
+      priority: 35
+      execution_timeout_secs: 36000
+      build_numbers: YES
+      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+      description_html: "This builder measures build performance for Linux developer builds, by simulating developer build scenarios on a high spec bot.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
+      contact_team_email: "chrome-build-team@google.com"
+    }
+    builders {
+      name: "linux-chromeos-build-perf"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builder:linux-chromeos-build-perf"
+      dimensions: "os:Ubuntu-22.04"
+      dimensions: "pool:luci.chromium.ci"
+      exe {
+        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
+        cipd_version: "refs/heads/main"
+        cmd: "luciexe"
+      }
+      properties:
+        '{'
+        '  "$build/chromium_tests_builder_config": {'
+        '    "builder_config": {'
+        '      "builder_db": {'
+        '        "entries": ['
+        '          {'
+        '            "builder_id": {'
+        '              "bucket": "build",'
+        '              "builder": "linux-chromeos-build-perf",'
+        '              "project": "chromium"'
+        '            },'
+        '            "builder_spec": {'
+        '              "builder_group": "chromium.build",'
+        '              "execution_mode": "COMPILE_AND_TEST",'
+        '              "legacy_chromium_config": {'
+        '                "apply_configs": ['
+        '                  "mb"'
+        '                ],'
+        '                "config": "chromium"'
+        '              },'
+        '              "legacy_gclient_config": {'
+        '                "apply_configs": ['
+        '                  "chromeos"'
+        '                ],'
+        '                "config": "chromium"'
+        '              }'
+        '            }'
+        '          }'
+        '        ]'
+        '      },'
+        '      "builder_ids": ['
+        '        {'
+        '          "bucket": "build",'
+        '          "builder": "linux-chromeos-build-perf",'
+        '          "project": "chromium"'
+        '        }'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$build/code_coverage": {'
+        '    "use_clang_coverage": true'
+        '  },'
+        '  "$build/reclient": {'
+        '    "instance": "rbe-chromium-untrusted",'
+        '    "jobs": 500,'
+        '    "metrics_project": "chromium-reclient-metrics",'
+        '    "scandeps_server": true'
+        '  },'
+        '  "$build/siso": {'
+        '    "configs": ['
+        '      "builder"'
+        '    ],'
+        '    "enable_cloud_profiler": true,'
+        '    "enable_cloud_trace": true,'
+        '    "experiments": [],'
+        '    "project": "rbe-chromium-untrusted"'
+        '  },'
+        '  "$recipe_engine/resultdb/test_presentation": {'
+        '    "column_keys": [],'
+        '    "grouping_keys": ['
+        '      "status",'
+        '      "v.test_suite"'
+        '    ]'
+        '  },'
+        '  "builder_group": "chromium.build",'
+        '  "recipe": "chrome_build/build_perf"'
+        '}'
+      priority: 35
+      execution_timeout_secs: 36000
+      build_numbers: YES
+      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+      description_html: "This builder measures ChromeOS build performance with and without remote caches.<br/>The build configs and the bot specs should be in sync with <a href=\"https://ci.chromium.org/p/chromium/builders/try/linux-chromeos-rel-compilator\">linux-chromeos-rel-compilator</a>.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
+      contact_team_email: "chrome-build-team@google.com"
+    }
+    builders {
+      name: "linux-chromeos-build-perf-siso"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builder:linux-chromeos-build-perf-siso"
+      dimensions: "os:Ubuntu-22.04"
+      dimensions: "pool:luci.chromium.ci"
+      exe {
+        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
+        cipd_version: "refs/heads/main"
+        cmd: "luciexe"
+      }
+      properties:
+        '{'
+        '  "$build/chromium_tests_builder_config": {'
+        '    "builder_config": {'
+        '      "builder_db": {'
+        '        "entries": ['
+        '          {'
+        '            "builder_id": {'
+        '              "bucket": "build",'
+        '              "builder": "linux-chromeos-build-perf-siso",'
+        '              "project": "chromium"'
+        '            },'
+        '            "builder_spec": {'
+        '              "builder_group": "chromium.build",'
+        '              "execution_mode": "COMPILE_AND_TEST",'
+        '              "legacy_chromium_config": {'
+        '                "apply_configs": ['
+        '                  "mb"'
+        '                ],'
+        '                "config": "chromium"'
+        '              },'
+        '              "legacy_gclient_config": {'
+        '                "apply_configs": ['
+        '                  "chromeos",'
+        '                  "siso_latest"'
+        '                ],'
+        '                "config": "chromium"'
+        '              }'
+        '            }'
+        '          }'
+        '        ]'
+        '      },'
+        '      "builder_ids": ['
+        '        {'
+        '          "bucket": "build",'
+        '          "builder": "linux-chromeos-build-perf-siso",'
+        '          "project": "chromium"'
+        '        }'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$build/code_coverage": {'
+        '    "use_clang_coverage": true'
+        '  },'
+        '  "$build/reclient": {'
+        '    "instance": "rbe-chromium-untrusted",'
+        '    "jobs": 500,'
+        '    "metrics_project": "chromium-reclient-metrics",'
+        '    "scandeps_server": true'
+        '  },'
+        '  "$build/siso": {'
+        '    "configs": ['
+        '      "builder"'
+        '    ],'
+        '    "enable_cloud_profiler": true,'
+        '    "enable_cloud_trace": true,'
+        '    "experiments": [],'
+        '    "project": "rbe-chromium-untrusted"'
+        '  },'
+        '  "$recipe_engine/resultdb/test_presentation": {'
+        '    "column_keys": [],'
+        '    "grouping_keys": ['
+        '      "status",'
+        '      "v.test_suite"'
+        '    ]'
+        '  },'
+        '  "builder_group": "chromium.build",'
+        '  "recipe": "chrome_build/build_perf_siso"'
+        '}'
+      priority: 35
+      execution_timeout_secs: 36000
+      build_numbers: YES
+      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+      description_html: "This builder measures ChromeOS build performance with Siso.<br/>The build configs and the bot specs should be in sync with <a href=\"https://ci.chromium.org/p/chromium/builders/try/linux-chromeos-rel-compilator\">linux-chromeos-rel-compilator</a>.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
+      contact_team_email: "chrome-build-team@google.com"
+    }
+    builders {
+      name: "mac-build-perf"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builder:mac-build-perf"
+      dimensions: "cpu:arm64"
+      dimensions: "os:Mac-13"
+      dimensions: "pool:luci.chromium.ci"
+      exe {
+        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
+        cipd_version: "refs/heads/main"
+        cmd: "luciexe"
+      }
+      properties:
+        '{'
+        '  "$build/chromium_tests_builder_config": {'
+        '    "builder_config": {'
+        '      "builder_db": {'
+        '        "entries": ['
+        '          {'
+        '            "builder_id": {'
+        '              "bucket": "build",'
+        '              "builder": "mac-build-perf",'
+        '              "project": "chromium"'
+        '            },'
+        '            "builder_spec": {'
+        '              "builder_group": "chromium.build",'
+        '              "execution_mode": "COMPILE_AND_TEST",'
+        '              "legacy_chromium_config": {'
+        '                "apply_configs": ['
+        '                  "mb"'
+        '                ],'
+        '                "build_config": "Release",'
+        '                "config": "chromium",'
+        '                "target_bits": 64,'
+        '                "target_platform": "mac"'
+        '              },'
+        '              "legacy_gclient_config": {'
+        '                "config": "chromium"'
+        '              }'
+        '            }'
+        '          }'
+        '        ]'
+        '      },'
+        '      "builder_ids": ['
+        '        {'
+        '          "bucket": "build",'
+        '          "builder": "mac-build-perf",'
+        '          "project": "chromium"'
+        '        }'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$build/code_coverage": {'
+        '    "use_clang_coverage": true'
+        '  },'
+        '  "$build/reclient": {'
+        '    "instance": "rbe-chromium-untrusted",'
+        '    "jobs": 500,'
+        '    "metrics_project": "chromium-reclient-metrics",'
+        '    "scandeps_server": true'
+        '  },'
+        '  "$build/siso": {'
+        '    "configs": ['
+        '      "builder"'
+        '    ],'
+        '    "enable_cloud_profiler": true,'
+        '    "enable_cloud_trace": true,'
+        '    "experiments": [],'
+        '    "project": "rbe-chromium-untrusted"'
+        '  },'
+        '  "$recipe_engine/resultdb/test_presentation": {'
+        '    "column_keys": [],'
+        '    "grouping_keys": ['
+        '      "status",'
+        '      "v.test_suite"'
+        '    ]'
+        '  },'
+        '  "builder_group": "chromium.build",'
+        '  "recipe": "chrome_build/build_perf"'
+        '}'
+      priority: 35
+      execution_timeout_secs: 36000
+      build_numbers: YES
+      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+      description_html: "This builder measures Mac build performance with and without remote caches.<br/>The build configs and the bot specs should be in sync with <a href=\"https://ci.chromium.org/p/chromium/builders/try/mac-rel-compilator\">mac-rel-compilator</a>.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
+      contact_team_email: "chrome-build-team@google.com"
+    }
+    builders {
+      name: "mac-build-perf-developer"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builder:mac-build-perf-developer"
+      dimensions: "cpu:arm64"
+      dimensions: "os:Mac-13"
+      dimensions: "pool:luci.chromium.ci"
+      exe {
+        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
+        cipd_version: "refs/heads/main"
+        cmd: "luciexe"
+      }
+      properties:
+        '{'
+        '  "$build/chromium_tests_builder_config": {'
+        '    "builder_config": {'
+        '      "builder_db": {'
+        '        "entries": ['
+        '          {'
+        '            "builder_id": {'
+        '              "bucket": "build",'
+        '              "builder": "mac-build-perf-developer",'
+        '              "project": "chromium"'
+        '            },'
+        '            "builder_spec": {'
+        '              "builder_group": "chromium.build",'
+        '              "execution_mode": "COMPILE_AND_TEST",'
+        '              "legacy_chromium_config": {'
+        '                "apply_configs": ['
+        '                  "mb"'
+        '                ],'
+        '                "config": "chromium"'
+        '              },'
+        '              "legacy_gclient_config": {'
+        '                "apply_configs": ['
+        '                  "siso_latest"'
+        '                ],'
+        '                "config": "chromium"'
+        '              }'
+        '            }'
+        '          }'
+        '        ]'
+        '      },'
+        '      "builder_ids": ['
+        '        {'
+        '          "bucket": "build",'
+        '          "builder": "mac-build-perf-developer",'
+        '          "project": "chromium"'
+        '        }'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$build/reclient": {'
+        '    "instance": "rbe-chromium-untrusted",'
+        '    "jobs": 800,'
+        '    "metrics_project": "chromium-reclient-metrics",'
+        '    "scandeps_server": true'
+        '  },'
+        '  "$build/siso": {'
+        '    "configs": [],'
+        '    "enable_cloud_profiler": true,'
+        '    "enable_cloud_trace": true,'
+        '    "experiments": [],'
+        '    "project": "rbe-chromium-untrusted"'
+        '  },'
+        '  "$recipe_engine/resultdb/test_presentation": {'
+        '    "column_keys": [],'
+        '    "grouping_keys": ['
+        '      "status",'
+        '      "v.test_suite"'
+        '    ]'
+        '  },'
+        '  "builder_group": "chromium.build",'
+        '  "recipe": "chrome_build/build_perf_developer"'
+        '}'
+      priority: 35
+      execution_timeout_secs: 36000
+      build_numbers: YES
+      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+      description_html: "This builder measures build performance for Mac developer builds, by simulating developer build scenarios on a bot.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
+      contact_team_email: "chrome-build-team@google.com"
+    }
+    builders {
+      name: "mac-build-perf-siso"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builder:mac-build-perf-siso"
+      dimensions: "cpu:arm64"
+      dimensions: "os:Mac-13"
+      dimensions: "pool:luci.chromium.ci"
+      exe {
+        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
+        cipd_version: "refs/heads/main"
+        cmd: "luciexe"
+      }
+      properties:
+        '{'
+        '  "$build/chromium_tests_builder_config": {'
+        '    "builder_config": {'
+        '      "builder_db": {'
+        '        "entries": ['
+        '          {'
+        '            "builder_id": {'
+        '              "bucket": "build",'
+        '              "builder": "mac-build-perf-siso",'
+        '              "project": "chromium"'
+        '            },'
+        '            "builder_spec": {'
+        '              "builder_group": "chromium.build",'
+        '              "execution_mode": "COMPILE_AND_TEST",'
+        '              "legacy_chromium_config": {'
+        '                "apply_configs": ['
+        '                  "mb"'
+        '                ],'
+        '                "build_config": "Release",'
+        '                "config": "chromium",'
+        '                "target_bits": 64,'
+        '                "target_platform": "mac"'
+        '              },'
+        '              "legacy_gclient_config": {'
+        '                "apply_configs": ['
+        '                  "siso_latest"'
+        '                ],'
+        '                "config": "chromium"'
+        '              }'
+        '            }'
+        '          }'
+        '        ]'
+        '      },'
+        '      "builder_ids": ['
+        '        {'
+        '          "bucket": "build",'
+        '          "builder": "mac-build-perf-siso",'
+        '          "project": "chromium"'
+        '        }'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$build/code_coverage": {'
+        '    "use_clang_coverage": true'
+        '  },'
+        '  "$build/reclient": {'
+        '    "instance": "rbe-chromium-untrusted",'
+        '    "jobs": 500,'
+        '    "metrics_project": "chromium-reclient-metrics",'
+        '    "scandeps_server": true'
+        '  },'
+        '  "$build/siso": {'
+        '    "configs": ['
+        '      "builder"'
+        '    ],'
+        '    "enable_cloud_profiler": true,'
+        '    "enable_cloud_trace": true,'
+        '    "experiments": [],'
+        '    "project": "rbe-chromium-untrusted"'
+        '  },'
+        '  "$recipe_engine/resultdb/test_presentation": {'
+        '    "column_keys": [],'
+        '    "grouping_keys": ['
+        '      "status",'
+        '      "v.test_suite"'
+        '    ]'
+        '  },'
+        '  "builder_group": "chromium.build",'
+        '  "recipe": "chrome_build/build_perf_siso"'
+        '}'
+      priority: 35
+      execution_timeout_secs: 36000
+      build_numbers: YES
+      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+      description_html: "This builder measures Mac build performance with Siso.<br/>The build configs and the bot specs should be in sync with <a href=\"https://ci.chromium.org/p/chromium/builders/try/mac-rel-compilator\">mac-rel-compilator</a>.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
+      contact_team_email: "chrome-build-team@google.com"
+    }
+    builders {
+      name: "win-build-perf-developer"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builder:win-build-perf-developer"
+      dimensions: "os:Windows-10"
+      dimensions: "pool:luci.chromium.ci"
+      exe {
+        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
+        cipd_version: "refs/heads/main"
+        cmd: "luciexe"
+      }
+      properties:
+        '{'
+        '  "$build/chromium_tests_builder_config": {'
+        '    "builder_config": {'
+        '      "builder_db": {'
+        '        "entries": ['
+        '          {'
+        '            "builder_id": {'
+        '              "bucket": "build",'
+        '              "builder": "win-build-perf-developer",'
+        '              "project": "chromium"'
+        '            },'
+        '            "builder_spec": {'
+        '              "builder_group": "chromium.build",'
+        '              "execution_mode": "COMPILE_AND_TEST",'
+        '              "legacy_chromium_config": {'
+        '                "apply_configs": ['
+        '                  "mb"'
+        '                ],'
+        '                "config": "chromium"'
+        '              },'
+        '              "legacy_gclient_config": {'
+        '                "apply_configs": ['
+        '                  "siso_latest"'
+        '                ],'
+        '                "config": "chromium"'
+        '              }'
+        '            }'
+        '          }'
+        '        ]'
+        '      },'
+        '      "builder_ids": ['
+        '        {'
+        '          "bucket": "build",'
+        '          "builder": "win-build-perf-developer",'
+        '          "project": "chromium"'
+        '        }'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$build/reclient": {'
+        '    "instance": "rbe-chromium-untrusted",'
+        '    "jobs": 1000,'
+        '    "metrics_project": "chromium-reclient-metrics",'
+        '    "scandeps_server": true'
+        '  },'
+        '  "$build/siso": {'
+        '    "configs": [],'
+        '    "enable_cloud_profiler": true,'
+        '    "enable_cloud_trace": true,'
+        '    "experiments": [],'
+        '    "project": "rbe-chromium-untrusted"'
+        '  },'
+        '  "$recipe_engine/resultdb/test_presentation": {'
+        '    "column_keys": [],'
+        '    "grouping_keys": ['
+        '      "status",'
+        '      "v.test_suite"'
+        '    ]'
+        '  },'
+        '  "builder_group": "chromium.build",'
+        '  "recipe": "chrome_build/build_perf_developer"'
+        '}'
+      priority: 35
+      execution_timeout_secs: 36000
+      build_numbers: YES
+      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+      description_html: "This builder measures build performance for Windows developer builds, by simulating developer build scenarios on a high spec bot.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
+      contact_team_email: "chrome-build-team@google.com"
+    }
+  }
+}
+buckets {
   name: "ci"
   swarming {
     builders {
@@ -28739,141 +30509,6 @@
       contact_team_email: "clank-engprod@google.com"
     }
     builders {
-      name: "android-build-perf-developer"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builder:android-build-perf-developer"
-      dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-22.04"
-      dimensions: "pool:luci.chromium.ci"
-      exe {
-        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
-        cipd_version: "refs/heads/main"
-        cmd: "luciexe"
-      }
-      properties:
-        '{'
-        '  "$build/chromium_tests_builder_config": {'
-        '    "builder_config": {'
-        '      "builder_db": {'
-        '        "entries": ['
-        '          {'
-        '            "builder_id": {'
-        '              "bucket": "ci",'
-        '              "builder": "android-build-perf-developer",'
-        '              "project": "chromium"'
-        '            },'
-        '            "builder_spec": {'
-        '              "builder_group": "chromium.build",'
-        '              "execution_mode": "COMPILE_AND_TEST",'
-        '              "legacy_android_config": {'
-        '                "config": "main_builder"'
-        '              },'
-        '              "legacy_chromium_config": {'
-        '                "apply_configs": ['
-        '                  "mb"'
-        '                ],'
-        '                "build_config": "Debug",'
-        '                "config": "android",'
-        '                "target_bits": 64,'
-        '                "target_platform": "android"'
-        '              },'
-        '              "legacy_gclient_config": {'
-        '                "apply_configs": ['
-        '                  "android",'
-        '                  "siso_latest"'
-        '                ],'
-        '                "config": "chromium"'
-        '              }'
-        '            }'
-        '          }'
-        '        ]'
-        '      },'
-        '      "builder_ids": ['
-        '        {'
-        '          "bucket": "ci",'
-        '          "builder": "android-build-perf-developer",'
-        '          "project": "chromium"'
-        '        }'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$build/reclient": {'
-        '    "instance": "rbe-chromium-untrusted",'
-        '    "jobs": 5120,'
-        '    "metrics_project": "chromium-reclient-metrics",'
-        '    "scandeps_server": true'
-        '  },'
-        '  "$build/siso": {'
-        '    "configs": [],'
-        '    "enable_cloud_profiler": true,'
-        '    "enable_cloud_trace": true,'
-        '    "experiments": [],'
-        '    "project": "rbe-chromium-untrusted"'
-        '  },'
-        '  "$recipe_engine/resultdb/test_presentation": {'
-        '    "column_keys": [],'
-        '    "grouping_keys": ['
-        '      "status",'
-        '      "v.test_suite"'
-        '    ]'
-        '  },'
-        '  "builder_group": "chromium.build",'
-        '  "recipe": "chrome_build/build_perf_developer"'
-        '}'
-      priority: 35
-      execution_timeout_secs: 36000
-      build_numbers: YES
-      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "chromium_swarming.expose_merge_script_failures"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-      description_html: "This builder measures build performance for Android developer builds, by simulating developer build scenarios on a high spec bot.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
-      shadow_builder_adjustments {
-        service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
-        pool: "luci.chromium.try"
-        dimensions: "builder:"
-        dimensions: "builderless:1"
-        dimensions: "pool:luci.chromium.try"
-      }
-    }
-    builders {
       name: "android-chrome-pie-x86-wpt-android-specific"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
@@ -32917,14 +34552,6 @@
         '  "builder_group": "chromium.infra",'
         '  "packages": ['
         '    {'
-        '      "cipd_yaml": "third_party/android_sdk/cipd/build-tools/25.0.2.yaml",'
-        '      "sdk_package_name": "build-tools;25.0.2"'
-        '    },'
-        '    {'
-        '      "cipd_yaml": "third_party/android_sdk/cipd/build-tools/33.0.0.yaml",'
-        '      "sdk_package_name": "build-tools;33.0.0"'
-        '    },'
-        '    {'
         '      "cipd_yaml": "third_party/android_sdk/cipd/build-tools/34.0.0.yaml",'
         '      "sdk_package_name": "build-tools;34.0.0"'
         '    },'
@@ -32937,30 +34564,14 @@
         '      "sdk_package_name": "emulator"'
         '    },'
         '    {'
-        '      "cipd_yaml": "third_party/android_sdk/cipd/patcher/v4.yaml",'
-        '      "sdk_package_name": "patcher;v4"'
-        '    },'
-        '    {'
-        '      "cipd_yaml": "third_party/android_sdk/cipd/platforms/android-33.yaml",'
-        '      "sdk_package_name": "platforms;android-33"'
-        '    },'
-        '    {'
         '      "cipd_yaml": "third_party/android_sdk/cipd/platforms/android-34.yaml",'
         '      "sdk_package_name": "platforms;android-34"'
         '    },'
         '    {'
-        '      "cipd_yaml": "third_party/android_sdk/cipd/platforms/android-TiramisuPrivacySandbox.yaml",'
-        '      "sdk_package_name": "platforms;android-TiramisuPrivacySandbox"'
-        '    },'
-        '    {'
         '      "cipd_yaml": "third_party/android_sdk/cipd/platform-tools.yaml",'
         '      "sdk_package_name": "platform-tools"'
         '    },'
         '    {'
-        '      "cipd_yaml": "third_party/android_sdk/cipd/sources/android-31.yaml",'
-        '      "sdk_package_name": "sources;android-31"'
-        '    },'
-        '    {'
         '      "cipd_yaml": "third_party/android_sdk/cipd/system_images/android-19/google_apis/x86.yaml",'
         '      "sdk_package_name": "system-images;android-19;google_apis;x86"'
         '    },'
@@ -33654,865 +35265,6 @@
       contact_team_email: "woa-engprod@google.com"
     }
     builders {
-      name: "build-perf-android"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builder:build-perf-android"
-      dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-22.04"
-      dimensions: "pool:luci.chromium.ci"
-      exe {
-        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
-        cipd_version: "refs/heads/main"
-        cmd: "luciexe"
-      }
-      properties:
-        '{'
-        '  "$build/chromium_tests_builder_config": {'
-        '    "builder_config": {'
-        '      "builder_db": {'
-        '        "entries": ['
-        '          {'
-        '            "builder_id": {'
-        '              "bucket": "ci",'
-        '              "builder": "build-perf-android",'
-        '              "project": "chromium"'
-        '            },'
-        '            "builder_spec": {'
-        '              "builder_group": "chromium.build",'
-        '              "execution_mode": "COMPILE_AND_TEST",'
-        '              "legacy_android_config": {'
-        '                "config": "main_builder"'
-        '              },'
-        '              "legacy_chromium_config": {'
-        '                "apply_configs": ['
-        '                  "mb"'
-        '                ],'
-        '                "build_config": "Release",'
-        '                "config": "android",'
-        '                "target_bits": 64,'
-        '                "target_platform": "android"'
-        '              },'
-        '              "legacy_gclient_config": {'
-        '                "apply_configs": ['
-        '                  "android"'
-        '                ],'
-        '                "config": "chromium"'
-        '              }'
-        '            }'
-        '          }'
-        '        ]'
-        '      },'
-        '      "builder_ids": ['
-        '        {'
-        '          "bucket": "ci",'
-        '          "builder": "build-perf-android",'
-        '          "project": "chromium"'
-        '        }'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$build/code_coverage": {'
-        '    "use_clang_coverage": true'
-        '  },'
-        '  "$build/reclient": {'
-        '    "instance": "rbe-chromium-untrusted",'
-        '    "jobs": 500,'
-        '    "metrics_project": "chromium-reclient-metrics",'
-        '    "scandeps_server": true'
-        '  },'
-        '  "$build/siso": {'
-        '    "configs": ['
-        '      "builder"'
-        '    ],'
-        '    "enable_cloud_profiler": true,'
-        '    "enable_cloud_trace": true,'
-        '    "experiments": [],'
-        '    "project": "rbe-chromium-untrusted"'
-        '  },'
-        '  "$recipe_engine/resultdb/test_presentation": {'
-        '    "column_keys": [],'
-        '    "grouping_keys": ['
-        '      "status",'
-        '      "v.test_suite"'
-        '    ]'
-        '  },'
-        '  "builder_group": "chromium.build",'
-        '  "recipe": "chrome_build/build_perf"'
-        '}'
-      priority: 35
-      execution_timeout_secs: 36000
-      build_numbers: YES
-      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "chromium_swarming.expose_merge_script_failures"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-      description_html: "This builder measures Android build performance with and without remote caches.<br/>The build configs and the bot specs should be in sync with <a href=\"https://ci.chromium.org/p/chromium/builders/try/android-arm64-rel-compilator\">android-arm64-rel-compilator</a>.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
-      shadow_builder_adjustments {
-        service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
-        pool: "luci.chromium.try"
-        properties:
-          '{'
-          '  "$build/reclient": {'
-          '    "instance": "rbe-chromium-untrusted",'
-          '    "jobs": 500,'
-          '    "metrics_project": "chromium-reclient-metrics",'
-          '    "scandeps_server": true'
-          '  }'
-          '}'
-        dimensions: "builder:"
-        dimensions: "builderless:1"
-        dimensions: "pool:luci.chromium.try"
-      }
-    }
-    builders {
-      name: "build-perf-android-siso"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builder:build-perf-android-siso"
-      dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-22.04"
-      dimensions: "pool:luci.chromium.ci"
-      exe {
-        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
-        cipd_version: "refs/heads/main"
-        cmd: "luciexe"
-      }
-      properties:
-        '{'
-        '  "$build/chromium_tests_builder_config": {'
-        '    "builder_config": {'
-        '      "builder_db": {'
-        '        "entries": ['
-        '          {'
-        '            "builder_id": {'
-        '              "bucket": "ci",'
-        '              "builder": "build-perf-android-siso",'
-        '              "project": "chromium"'
-        '            },'
-        '            "builder_spec": {'
-        '              "builder_group": "chromium.build",'
-        '              "execution_mode": "COMPILE_AND_TEST",'
-        '              "legacy_android_config": {'
-        '                "config": "main_builder"'
-        '              },'
-        '              "legacy_chromium_config": {'
-        '                "apply_configs": ['
-        '                  "mb"'
-        '                ],'
-        '                "build_config": "Release",'
-        '                "config": "android",'
-        '                "target_bits": 64,'
-        '                "target_platform": "android"'
-        '              },'
-        '              "legacy_gclient_config": {'
-        '                "apply_configs": ['
-        '                  "android",'
-        '                  "siso_latest"'
-        '                ],'
-        '                "config": "chromium"'
-        '              }'
-        '            }'
-        '          }'
-        '        ]'
-        '      },'
-        '      "builder_ids": ['
-        '        {'
-        '          "bucket": "ci",'
-        '          "builder": "build-perf-android-siso",'
-        '          "project": "chromium"'
-        '        }'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$build/code_coverage": {'
-        '    "use_clang_coverage": true'
-        '  },'
-        '  "$build/reclient": {'
-        '    "instance": "rbe-chromium-untrusted",'
-        '    "jobs": 500,'
-        '    "metrics_project": "chromium-reclient-metrics",'
-        '    "scandeps_server": true'
-        '  },'
-        '  "$build/siso": {'
-        '    "configs": ['
-        '      "builder"'
-        '    ],'
-        '    "enable_cloud_profiler": true,'
-        '    "enable_cloud_trace": true,'
-        '    "experiments": [],'
-        '    "project": "rbe-chromium-untrusted"'
-        '  },'
-        '  "$recipe_engine/resultdb/test_presentation": {'
-        '    "column_keys": [],'
-        '    "grouping_keys": ['
-        '      "status",'
-        '      "v.test_suite"'
-        '    ]'
-        '  },'
-        '  "builder_group": "chromium.build",'
-        '  "recipe": "chrome_build/build_perf_siso"'
-        '}'
-      priority: 35
-      execution_timeout_secs: 36000
-      build_numbers: YES
-      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "chromium_swarming.expose_merge_script_failures"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-      description_html: "This builder measures Android build performance with Siso<br/>The build configs and the bot specs should be in sync with <a href=\"https://ci.chromium.org/p/chromium/builders/try/android-arm64-rel-compilator\">android-arm64-rel-compilator</a>.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
-      shadow_builder_adjustments {
-        service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
-        pool: "luci.chromium.try"
-        properties:
-          '{'
-          '  "$build/reclient": {'
-          '    "instance": "rbe-chromium-untrusted",'
-          '    "jobs": 500,'
-          '    "metrics_project": "chromium-reclient-metrics",'
-          '    "scandeps_server": true'
-          '  }'
-          '}'
-        dimensions: "builder:"
-        dimensions: "builderless:1"
-        dimensions: "pool:luci.chromium.try"
-      }
-    }
-    builders {
-      name: "build-perf-linux"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builder:build-perf-linux"
-      dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-22.04"
-      dimensions: "pool:luci.chromium.ci"
-      exe {
-        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
-        cipd_version: "refs/heads/main"
-        cmd: "luciexe"
-      }
-      properties:
-        '{'
-        '  "$build/chromium_tests_builder_config": {'
-        '    "builder_config": {'
-        '      "builder_db": {'
-        '        "entries": ['
-        '          {'
-        '            "builder_id": {'
-        '              "bucket": "ci",'
-        '              "builder": "build-perf-linux",'
-        '              "project": "chromium"'
-        '            },'
-        '            "builder_spec": {'
-        '              "builder_group": "chromium.build",'
-        '              "execution_mode": "COMPILE_AND_TEST",'
-        '              "legacy_chromium_config": {'
-        '                "apply_configs": ['
-        '                  "mb"'
-        '                ],'
-        '                "config": "chromium"'
-        '              },'
-        '              "legacy_gclient_config": {'
-        '                "config": "chromium"'
-        '              }'
-        '            }'
-        '          }'
-        '        ]'
-        '      },'
-        '      "builder_ids": ['
-        '        {'
-        '          "bucket": "ci",'
-        '          "builder": "build-perf-linux",'
-        '          "project": "chromium"'
-        '        }'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$build/code_coverage": {'
-        '    "use_clang_coverage": true'
-        '  },'
-        '  "$build/reclient": {'
-        '    "instance": "rbe-chromium-untrusted",'
-        '    "jobs": 500,'
-        '    "metrics_project": "chromium-reclient-metrics",'
-        '    "scandeps_server": true'
-        '  },'
-        '  "$build/siso": {'
-        '    "configs": ['
-        '      "builder"'
-        '    ],'
-        '    "enable_cloud_profiler": true,'
-        '    "enable_cloud_trace": true,'
-        '    "experiments": [],'
-        '    "project": "rbe-chromium-untrusted"'
-        '  },'
-        '  "$recipe_engine/resultdb/test_presentation": {'
-        '    "column_keys": [],'
-        '    "grouping_keys": ['
-        '      "status",'
-        '      "v.test_suite"'
-        '    ]'
-        '  },'
-        '  "builder_group": "chromium.build",'
-        '  "recipe": "chrome_build/build_perf"'
-        '}'
-      priority: 35
-      execution_timeout_secs: 36000
-      build_numbers: YES
-      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "chromium_swarming.expose_merge_script_failures"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-      description_html: "This builder measures Linux build performance with and without remote caches.<br/>The build configs and the bot specs should be in sync with <a href=\"https://ci.chromium.org/p/chromium/builders/try/linux-rel-compilator\">linux-rel-compilator</a>.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
-      shadow_builder_adjustments {
-        service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
-        pool: "luci.chromium.try"
-        properties:
-          '{'
-          '  "$build/reclient": {'
-          '    "instance": "rbe-chromium-untrusted",'
-          '    "jobs": 500,'
-          '    "metrics_project": "chromium-reclient-metrics",'
-          '    "scandeps_server": true'
-          '  }'
-          '}'
-        dimensions: "builder:"
-        dimensions: "builderless:1"
-        dimensions: "pool:luci.chromium.try"
-      }
-    }
-    builders {
-      name: "build-perf-linux-siso"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builder:build-perf-linux-siso"
-      dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-22.04"
-      dimensions: "pool:luci.chromium.ci"
-      exe {
-        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
-        cipd_version: "refs/heads/main"
-        cmd: "luciexe"
-      }
-      properties:
-        '{'
-        '  "$build/chromium_tests_builder_config": {'
-        '    "builder_config": {'
-        '      "builder_db": {'
-        '        "entries": ['
-        '          {'
-        '            "builder_id": {'
-        '              "bucket": "ci",'
-        '              "builder": "build-perf-linux-siso",'
-        '              "project": "chromium"'
-        '            },'
-        '            "builder_spec": {'
-        '              "builder_group": "chromium.build",'
-        '              "execution_mode": "COMPILE_AND_TEST",'
-        '              "legacy_chromium_config": {'
-        '                "apply_configs": ['
-        '                  "mb"'
-        '                ],'
-        '                "config": "chromium"'
-        '              },'
-        '              "legacy_gclient_config": {'
-        '                "apply_configs": ['
-        '                  "siso_latest"'
-        '                ],'
-        '                "config": "chromium"'
-        '              }'
-        '            }'
-        '          }'
-        '        ]'
-        '      },'
-        '      "builder_ids": ['
-        '        {'
-        '          "bucket": "ci",'
-        '          "builder": "build-perf-linux-siso",'
-        '          "project": "chromium"'
-        '        }'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$build/code_coverage": {'
-        '    "use_clang_coverage": true'
-        '  },'
-        '  "$build/reclient": {'
-        '    "instance": "rbe-chromium-untrusted",'
-        '    "jobs": 500,'
-        '    "metrics_project": "chromium-reclient-metrics",'
-        '    "scandeps_server": true'
-        '  },'
-        '  "$build/siso": {'
-        '    "configs": ['
-        '      "builder"'
-        '    ],'
-        '    "enable_cloud_profiler": true,'
-        '    "enable_cloud_trace": true,'
-        '    "experiments": [],'
-        '    "project": "rbe-chromium-untrusted"'
-        '  },'
-        '  "$recipe_engine/resultdb/test_presentation": {'
-        '    "column_keys": [],'
-        '    "grouping_keys": ['
-        '      "status",'
-        '      "v.test_suite"'
-        '    ]'
-        '  },'
-        '  "builder_group": "chromium.build",'
-        '  "recipe": "chrome_build/build_perf_siso"'
-        '}'
-      priority: 35
-      execution_timeout_secs: 36000
-      build_numbers: YES
-      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "chromium_swarming.expose_merge_script_failures"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-      description_html: "This builder measures Linux build performance with Siso.<br/>The build configs and the bot specs should be in sync with <a href=\"https://ci.chromium.org/p/chromium/builders/try/linux-rel-compilator\">linux-rel-compilator</a>.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
-      shadow_builder_adjustments {
-        service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
-        pool: "luci.chromium.try"
-        properties:
-          '{'
-          '  "$build/reclient": {'
-          '    "instance": "rbe-chromium-untrusted",'
-          '    "jobs": 500,'
-          '    "metrics_project": "chromium-reclient-metrics",'
-          '    "scandeps_server": true'
-          '  }'
-          '}'
-        dimensions: "builder:"
-        dimensions: "builderless:1"
-        dimensions: "pool:luci.chromium.try"
-      }
-    }
-    builders {
-      name: "build-perf-windows"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builder:build-perf-windows"
-      dimensions: "cpu:x86-64"
-      dimensions: "os:Windows-10"
-      dimensions: "pool:luci.chromium.ci"
-      exe {
-        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
-        cipd_version: "refs/heads/main"
-        cmd: "luciexe"
-      }
-      properties:
-        '{'
-        '  "$build/chromium_tests_builder_config": {'
-        '    "builder_config": {'
-        '      "builder_db": {'
-        '        "entries": ['
-        '          {'
-        '            "builder_id": {'
-        '              "bucket": "ci",'
-        '              "builder": "build-perf-windows",'
-        '              "project": "chromium"'
-        '            },'
-        '            "builder_spec": {'
-        '              "builder_group": "chromium.build",'
-        '              "execution_mode": "COMPILE_AND_TEST",'
-        '              "legacy_chromium_config": {'
-        '                "apply_configs": ['
-        '                  "mb"'
-        '                ],'
-        '                "config": "chromium"'
-        '              },'
-        '              "legacy_gclient_config": {'
-        '                "config": "chromium"'
-        '              }'
-        '            }'
-        '          }'
-        '        ]'
-        '      },'
-        '      "builder_ids": ['
-        '        {'
-        '          "bucket": "ci",'
-        '          "builder": "build-perf-windows",'
-        '          "project": "chromium"'
-        '        }'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$build/code_coverage": {'
-        '    "use_clang_coverage": true'
-        '  },'
-        '  "$build/reclient": {'
-        '    "instance": "rbe-chromium-untrusted",'
-        '    "jobs": 500,'
-        '    "metrics_project": "chromium-reclient-metrics",'
-        '    "scandeps_server": true'
-        '  },'
-        '  "$build/siso": {'
-        '    "configs": ['
-        '      "builder"'
-        '    ],'
-        '    "enable_cloud_profiler": true,'
-        '    "enable_cloud_trace": true,'
-        '    "experiments": [],'
-        '    "project": "rbe-chromium-untrusted"'
-        '  },'
-        '  "$recipe_engine/resultdb/test_presentation": {'
-        '    "column_keys": [],'
-        '    "grouping_keys": ['
-        '      "status",'
-        '      "v.test_suite"'
-        '    ]'
-        '  },'
-        '  "builder_group": "chromium.build",'
-        '  "recipe": "chrome_build/build_perf"'
-        '}'
-      priority: 35
-      execution_timeout_secs: 36000
-      build_numbers: YES
-      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "chromium_swarming.expose_merge_script_failures"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-      description_html: "This builder measures Windows build performance with and without remote caches.<br/>The build configs and the bot specs should be in sync with <a href=\"https://ci.chromium.org/p/chromium/builders/try/win-rel-compilator\">win-rel-compilator</a>.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
-      shadow_builder_adjustments {
-        service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
-        pool: "luci.chromium.try"
-        properties:
-          '{'
-          '  "$build/reclient": {'
-          '    "instance": "rbe-chromium-untrusted",'
-          '    "jobs": 500,'
-          '    "metrics_project": "chromium-reclient-metrics",'
-          '    "scandeps_server": true'
-          '  }'
-          '}'
-        dimensions: "builder:"
-        dimensions: "builderless:1"
-        dimensions: "pool:luci.chromium.try"
-      }
-    }
-    builders {
-      name: "build-perf-windows-siso"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builder:build-perf-windows-siso"
-      dimensions: "cpu:x86-64"
-      dimensions: "os:Windows-10"
-      dimensions: "pool:luci.chromium.ci"
-      exe {
-        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
-        cipd_version: "refs/heads/main"
-        cmd: "luciexe"
-      }
-      properties:
-        '{'
-        '  "$build/chromium_tests_builder_config": {'
-        '    "builder_config": {'
-        '      "builder_db": {'
-        '        "entries": ['
-        '          {'
-        '            "builder_id": {'
-        '              "bucket": "ci",'
-        '              "builder": "build-perf-windows-siso",'
-        '              "project": "chromium"'
-        '            },'
-        '            "builder_spec": {'
-        '              "builder_group": "chromium.build",'
-        '              "execution_mode": "COMPILE_AND_TEST",'
-        '              "legacy_chromium_config": {'
-        '                "apply_configs": ['
-        '                  "mb"'
-        '                ],'
-        '                "config": "chromium"'
-        '              },'
-        '              "legacy_gclient_config": {'
-        '                "apply_configs": ['
-        '                  "siso_latest"'
-        '                ],'
-        '                "config": "chromium"'
-        '              }'
-        '            }'
-        '          }'
-        '        ]'
-        '      },'
-        '      "builder_ids": ['
-        '        {'
-        '          "bucket": "ci",'
-        '          "builder": "build-perf-windows-siso",'
-        '          "project": "chromium"'
-        '        }'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$build/code_coverage": {'
-        '    "use_clang_coverage": true'
-        '  },'
-        '  "$build/reclient": {'
-        '    "instance": "rbe-chromium-untrusted",'
-        '    "jobs": 500,'
-        '    "metrics_project": "chromium-reclient-metrics",'
-        '    "scandeps_server": true'
-        '  },'
-        '  "$build/siso": {'
-        '    "configs": ['
-        '      "builder"'
-        '    ],'
-        '    "enable_cloud_profiler": true,'
-        '    "enable_cloud_trace": true,'
-        '    "experiments": [],'
-        '    "project": "rbe-chromium-untrusted"'
-        '  },'
-        '  "$recipe_engine/resultdb/test_presentation": {'
-        '    "column_keys": [],'
-        '    "grouping_keys": ['
-        '      "status",'
-        '      "v.test_suite"'
-        '    ]'
-        '  },'
-        '  "builder_group": "chromium.build",'
-        '  "recipe": "chrome_build/build_perf_siso"'
-        '}'
-      priority: 35
-      execution_timeout_secs: 36000
-      build_numbers: YES
-      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "chromium_swarming.expose_merge_script_failures"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-      description_html: "This builder measures Windows build performance with Siso.<br/>The build configs and the bot specs should be in sync with <a href=\"https://ci.chromium.org/p/chromium/builders/try/win-rel-compilator\">win-rel-compilator</a>.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
-      shadow_builder_adjustments {
-        service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
-        pool: "luci.chromium.try"
-        properties:
-          '{'
-          '  "$build/reclient": {'
-          '    "instance": "rbe-chromium-untrusted",'
-          '    "jobs": 500,'
-          '    "metrics_project": "chromium-reclient-metrics",'
-          '    "scandeps_server": true'
-          '  }'
-          '}'
-        dimensions: "builder:"
-        dimensions: "builderless:1"
-        dimensions: "pool:luci.chromium.try"
-      }
-    }
-    builders {
       name: "chromeos-amd64-generic-asan-rel"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
@@ -35841,6 +36593,100 @@
       }
     }
     builders {
+      name: "chromeos-jacuzzi-rel-skylab-fyi"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builderless:1"
+      dimensions: "cores:8"
+      dimensions: "cpu:x86-64"
+      dimensions: "free_space:standard"
+      dimensions: "os:Ubuntu-22.04"
+      dimensions: "pool:luci.chromium.ci"
+      dimensions: "ssd:0"
+      exe {
+        cipd_package: "infra/chromium/bootstrapper/${platform}"
+        cipd_version: "latest"
+        cmd: "bootstrapper"
+      }
+      properties:
+        '{'
+        '  "$bootstrap/exe": {'
+        '    "exe": {'
+        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
+        '      "cipd_version": "refs/heads/main",'
+        '      "cmd": ['
+        '        "luciexe"'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$bootstrap/properties": {'
+        '    "properties_file": "infra/config/generated/builders/ci/chromeos-jacuzzi-rel-skylab-fyi/properties.json",'
+        '    "shadow_properties_file": "infra/config/generated/builders/ci/chromeos-jacuzzi-rel-skylab-fyi/shadow-properties.json",'
+        '    "top_level_project": {'
+        '      "ref": "refs/heads/main",'
+        '      "repo": {'
+        '        "host": "chromium.googlesource.com",'
+        '        "project": "chromium/src"'
+        '      }'
+        '    }'
+        '  },'
+        '  "builder_group": "chromium.fyi",'
+        '  "led_builder_is_bootstrapped": true,'
+        '  "recipe": "chromium"'
+        '}'
+      priority: 35
+      execution_timeout_secs: 36000
+      build_numbers: YES
+      service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "ci_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_ci_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+      description_html: "This builder builds public image and runs tests on DUTs in the lab.<br/>This is experimental.\n<br/>This builder is mirrored by any of the following try builders:<br/><ul><li><a href=\"https://ci.chromium.org/p/chromium/builders/try/chromeos-jacuzzi-rel-skylab\">chromeos-jacuzzi-rel-skylab</a></li></ul>"
+      shadow_builder_adjustments {
+        service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
+        pool: "luci.chromium.try"
+        dimensions: "free_space:"
+        dimensions: "pool:luci.chromium.try"
+      }
+      contact_team_email: "chromeos-velocity@google.com"
+    }
+    builders {
       name: "chromeos-js-code-coverage"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
@@ -42240,134 +43086,6 @@
       }
     }
     builders {
-      name: "linux-build-perf-developer"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builder:linux-build-perf-developer"
-      dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-22.04"
-      dimensions: "pool:luci.chromium.ci"
-      exe {
-        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
-        cipd_version: "refs/heads/main"
-        cmd: "luciexe"
-      }
-      properties:
-        '{'
-        '  "$build/chromium_tests_builder_config": {'
-        '    "builder_config": {'
-        '      "builder_db": {'
-        '        "entries": ['
-        '          {'
-        '            "builder_id": {'
-        '              "bucket": "ci",'
-        '              "builder": "linux-build-perf-developer",'
-        '              "project": "chromium"'
-        '            },'
-        '            "builder_spec": {'
-        '              "builder_group": "chromium.build",'
-        '              "execution_mode": "COMPILE_AND_TEST",'
-        '              "legacy_chromium_config": {'
-        '                "apply_configs": ['
-        '                  "mb"'
-        '                ],'
-        '                "config": "chromium"'
-        '              },'
-        '              "legacy_gclient_config": {'
-        '                "apply_configs": ['
-        '                  "siso_latest"'
-        '                ],'
-        '                "config": "chromium"'
-        '              }'
-        '            }'
-        '          }'
-        '        ]'
-        '      },'
-        '      "builder_ids": ['
-        '        {'
-        '          "bucket": "ci",'
-        '          "builder": "linux-build-perf-developer",'
-        '          "project": "chromium"'
-        '        }'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$build/reclient": {'
-        '    "instance": "rbe-chromium-untrusted",'
-        '    "jobs": 5120,'
-        '    "metrics_project": "chromium-reclient-metrics",'
-        '    "scandeps_server": true'
-        '  },'
-        '  "$build/siso": {'
-        '    "configs": [],'
-        '    "enable_cloud_profiler": true,'
-        '    "enable_cloud_trace": true,'
-        '    "experiments": [],'
-        '    "project": "rbe-chromium-untrusted"'
-        '  },'
-        '  "$recipe_engine/resultdb/test_presentation": {'
-        '    "column_keys": [],'
-        '    "grouping_keys": ['
-        '      "status",'
-        '      "v.test_suite"'
-        '    ]'
-        '  },'
-        '  "builder_group": "chromium.build",'
-        '  "recipe": "chrome_build/build_perf_developer"'
-        '}'
-      priority: 35
-      execution_timeout_secs: 36000
-      build_numbers: YES
-      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "chromium_swarming.expose_merge_script_failures"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-      description_html: "This builder measures build performance for Linux developer builds, by simulating developer build scenarios on a high spec bot.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
-      shadow_builder_adjustments {
-        service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
-        pool: "luci.chromium.try"
-        dimensions: "builder:"
-        dimensions: "builderless:1"
-        dimensions: "pool:luci.chromium.try"
-      }
-    }
-    builders {
       name: "linux-cfm-rel"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
@@ -42651,291 +43369,6 @@
       }
     }
     builders {
-      name: "linux-chromeos-build-perf"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builder:linux-chromeos-build-perf"
-      dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-22.04"
-      dimensions: "pool:luci.chromium.ci"
-      exe {
-        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
-        cipd_version: "refs/heads/main"
-        cmd: "luciexe"
-      }
-      properties:
-        '{'
-        '  "$build/chromium_tests_builder_config": {'
-        '    "builder_config": {'
-        '      "builder_db": {'
-        '        "entries": ['
-        '          {'
-        '            "builder_id": {'
-        '              "bucket": "ci",'
-        '              "builder": "linux-chromeos-build-perf",'
-        '              "project": "chromium"'
-        '            },'
-        '            "builder_spec": {'
-        '              "builder_group": "chromium.build",'
-        '              "execution_mode": "COMPILE_AND_TEST",'
-        '              "legacy_chromium_config": {'
-        '                "apply_configs": ['
-        '                  "mb"'
-        '                ],'
-        '                "config": "chromium"'
-        '              },'
-        '              "legacy_gclient_config": {'
-        '                "apply_configs": ['
-        '                  "chromeos"'
-        '                ],'
-        '                "config": "chromium"'
-        '              }'
-        '            }'
-        '          }'
-        '        ]'
-        '      },'
-        '      "builder_ids": ['
-        '        {'
-        '          "bucket": "ci",'
-        '          "builder": "linux-chromeos-build-perf",'
-        '          "project": "chromium"'
-        '        }'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$build/code_coverage": {'
-        '    "use_clang_coverage": true'
-        '  },'
-        '  "$build/reclient": {'
-        '    "instance": "rbe-chromium-untrusted",'
-        '    "jobs": 500,'
-        '    "metrics_project": "chromium-reclient-metrics",'
-        '    "scandeps_server": true'
-        '  },'
-        '  "$build/siso": {'
-        '    "configs": ['
-        '      "builder"'
-        '    ],'
-        '    "enable_cloud_profiler": true,'
-        '    "enable_cloud_trace": true,'
-        '    "experiments": [],'
-        '    "project": "rbe-chromium-untrusted"'
-        '  },'
-        '  "$recipe_engine/resultdb/test_presentation": {'
-        '    "column_keys": [],'
-        '    "grouping_keys": ['
-        '      "status",'
-        '      "v.test_suite"'
-        '    ]'
-        '  },'
-        '  "builder_group": "chromium.build",'
-        '  "recipe": "chrome_build/build_perf"'
-        '}'
-      priority: 35
-      execution_timeout_secs: 36000
-      build_numbers: YES
-      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "chromium_swarming.expose_merge_script_failures"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-      description_html: "This builder measures ChromeOS build performance with and without remote caches.<br/>The build configs and the bot specs should be in sync with <a href=\"https://ci.chromium.org/p/chromium/builders/try/linux-chromeos-rel-compilator\">linux-chromeos-rel-compilator</a>.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
-      shadow_builder_adjustments {
-        service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
-        pool: "luci.chromium.try"
-        properties:
-          '{'
-          '  "$build/reclient": {'
-          '    "instance": "rbe-chromium-untrusted",'
-          '    "jobs": 500,'
-          '    "metrics_project": "chromium-reclient-metrics",'
-          '    "scandeps_server": true'
-          '  }'
-          '}'
-        dimensions: "builder:"
-        dimensions: "builderless:1"
-        dimensions: "pool:luci.chromium.try"
-      }
-    }
-    builders {
-      name: "linux-chromeos-build-perf-siso"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builder:linux-chromeos-build-perf-siso"
-      dimensions: "cpu:x86-64"
-      dimensions: "os:Ubuntu-22.04"
-      dimensions: "pool:luci.chromium.ci"
-      exe {
-        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
-        cipd_version: "refs/heads/main"
-        cmd: "luciexe"
-      }
-      properties:
-        '{'
-        '  "$build/chromium_tests_builder_config": {'
-        '    "builder_config": {'
-        '      "builder_db": {'
-        '        "entries": ['
-        '          {'
-        '            "builder_id": {'
-        '              "bucket": "ci",'
-        '              "builder": "linux-chromeos-build-perf-siso",'
-        '              "project": "chromium"'
-        '            },'
-        '            "builder_spec": {'
-        '              "builder_group": "chromium.build",'
-        '              "execution_mode": "COMPILE_AND_TEST",'
-        '              "legacy_chromium_config": {'
-        '                "apply_configs": ['
-        '                  "mb"'
-        '                ],'
-        '                "config": "chromium"'
-        '              },'
-        '              "legacy_gclient_config": {'
-        '                "apply_configs": ['
-        '                  "chromeos",'
-        '                  "siso_latest"'
-        '                ],'
-        '                "config": "chromium"'
-        '              }'
-        '            }'
-        '          }'
-        '        ]'
-        '      },'
-        '      "builder_ids": ['
-        '        {'
-        '          "bucket": "ci",'
-        '          "builder": "linux-chromeos-build-perf-siso",'
-        '          "project": "chromium"'
-        '        }'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$build/code_coverage": {'
-        '    "use_clang_coverage": true'
-        '  },'
-        '  "$build/reclient": {'
-        '    "instance": "rbe-chromium-untrusted",'
-        '    "jobs": 500,'
-        '    "metrics_project": "chromium-reclient-metrics",'
-        '    "scandeps_server": true'
-        '  },'
-        '  "$build/siso": {'
-        '    "configs": ['
-        '      "builder"'
-        '    ],'
-        '    "enable_cloud_profiler": true,'
-        '    "enable_cloud_trace": true,'
-        '    "experiments": [],'
-        '    "project": "rbe-chromium-untrusted"'
-        '  },'
-        '  "$recipe_engine/resultdb/test_presentation": {'
-        '    "column_keys": [],'
-        '    "grouping_keys": ['
-        '      "status",'
-        '      "v.test_suite"'
-        '    ]'
-        '  },'
-        '  "builder_group": "chromium.build",'
-        '  "recipe": "chrome_build/build_perf_siso"'
-        '}'
-      priority: 35
-      execution_timeout_secs: 36000
-      build_numbers: YES
-      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "chromium_swarming.expose_merge_script_failures"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-      description_html: "This builder measures ChromeOS build performance with Siso.<br/>The build configs and the bot specs should be in sync with <a href=\"https://ci.chromium.org/p/chromium/builders/try/linux-chromeos-rel-compilator\">linux-chromeos-rel-compilator</a>.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
-      shadow_builder_adjustments {
-        service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
-        pool: "luci.chromium.try"
-        properties:
-          '{'
-          '  "$build/reclient": {'
-          '    "instance": "rbe-chromium-untrusted",'
-          '    "jobs": 500,'
-          '    "metrics_project": "chromium-reclient-metrics",'
-          '    "scandeps_server": true'
-          '  }'
-          '}'
-        dimensions: "builder:"
-        dimensions: "builderless:1"
-        dimensions: "pool:luci.chromium.try"
-      }
-    }
-    builders {
       name: "linux-chromeos-code-coverage"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
@@ -48765,421 +49198,6 @@
       contact_team_email: "bling-engprod@google.com"
     }
     builders {
-      name: "mac-build-perf"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builder:mac-build-perf"
-      dimensions: "cpu:arm64"
-      dimensions: "os:Mac-13"
-      dimensions: "pool:luci.chromium.ci"
-      exe {
-        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
-        cipd_version: "refs/heads/main"
-        cmd: "luciexe"
-      }
-      properties:
-        '{'
-        '  "$build/chromium_tests_builder_config": {'
-        '    "builder_config": {'
-        '      "builder_db": {'
-        '        "entries": ['
-        '          {'
-        '            "builder_id": {'
-        '              "bucket": "ci",'
-        '              "builder": "mac-build-perf",'
-        '              "project": "chromium"'
-        '            },'
-        '            "builder_spec": {'
-        '              "builder_group": "chromium.build",'
-        '              "execution_mode": "COMPILE_AND_TEST",'
-        '              "legacy_chromium_config": {'
-        '                "apply_configs": ['
-        '                  "mb"'
-        '                ],'
-        '                "build_config": "Release",'
-        '                "config": "chromium",'
-        '                "target_bits": 64,'
-        '                "target_platform": "mac"'
-        '              },'
-        '              "legacy_gclient_config": {'
-        '                "config": "chromium"'
-        '              }'
-        '            }'
-        '          }'
-        '        ]'
-        '      },'
-        '      "builder_ids": ['
-        '        {'
-        '          "bucket": "ci",'
-        '          "builder": "mac-build-perf",'
-        '          "project": "chromium"'
-        '        }'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$build/code_coverage": {'
-        '    "use_clang_coverage": true'
-        '  },'
-        '  "$build/reclient": {'
-        '    "instance": "rbe-chromium-untrusted",'
-        '    "jobs": 500,'
-        '    "metrics_project": "chromium-reclient-metrics",'
-        '    "scandeps_server": true'
-        '  },'
-        '  "$build/siso": {'
-        '    "configs": ['
-        '      "builder"'
-        '    ],'
-        '    "enable_cloud_profiler": true,'
-        '    "enable_cloud_trace": true,'
-        '    "experiments": [],'
-        '    "project": "rbe-chromium-untrusted"'
-        '  },'
-        '  "$recipe_engine/resultdb/test_presentation": {'
-        '    "column_keys": [],'
-        '    "grouping_keys": ['
-        '      "status",'
-        '      "v.test_suite"'
-        '    ]'
-        '  },'
-        '  "builder_group": "chromium.build",'
-        '  "recipe": "chrome_build/build_perf"'
-        '}'
-      priority: 35
-      execution_timeout_secs: 36000
-      build_numbers: YES
-      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "chromium_swarming.expose_merge_script_failures"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-      description_html: "This builder measures Mac build performance with and without remote caches.<br/>The build configs and the bot specs should be in sync with <a href=\"https://ci.chromium.org/p/chromium/builders/try/mac-rel-compilator\">mac-rel-compilator</a>.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
-      shadow_builder_adjustments {
-        service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
-        pool: "luci.chromium.try"
-        properties:
-          '{'
-          '  "$build/reclient": {'
-          '    "instance": "rbe-chromium-untrusted",'
-          '    "jobs": 500,'
-          '    "metrics_project": "chromium-reclient-metrics",'
-          '    "scandeps_server": true'
-          '  }'
-          '}'
-        dimensions: "builder:"
-        dimensions: "builderless:1"
-        dimensions: "pool:luci.chromium.try"
-      }
-    }
-    builders {
-      name: "mac-build-perf-developer"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builder:mac-build-perf-developer"
-      dimensions: "cpu:arm64"
-      dimensions: "os:Mac-13"
-      dimensions: "pool:luci.chromium.ci"
-      exe {
-        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
-        cipd_version: "refs/heads/main"
-        cmd: "luciexe"
-      }
-      properties:
-        '{'
-        '  "$build/chromium_tests_builder_config": {'
-        '    "builder_config": {'
-        '      "builder_db": {'
-        '        "entries": ['
-        '          {'
-        '            "builder_id": {'
-        '              "bucket": "ci",'
-        '              "builder": "mac-build-perf-developer",'
-        '              "project": "chromium"'
-        '            },'
-        '            "builder_spec": {'
-        '              "builder_group": "chromium.build",'
-        '              "execution_mode": "COMPILE_AND_TEST",'
-        '              "legacy_chromium_config": {'
-        '                "apply_configs": ['
-        '                  "mb"'
-        '                ],'
-        '                "config": "chromium"'
-        '              },'
-        '              "legacy_gclient_config": {'
-        '                "apply_configs": ['
-        '                  "siso_latest"'
-        '                ],'
-        '                "config": "chromium"'
-        '              }'
-        '            }'
-        '          }'
-        '        ]'
-        '      },'
-        '      "builder_ids": ['
-        '        {'
-        '          "bucket": "ci",'
-        '          "builder": "mac-build-perf-developer",'
-        '          "project": "chromium"'
-        '        }'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$build/reclient": {'
-        '    "instance": "rbe-chromium-untrusted",'
-        '    "jobs": 800,'
-        '    "metrics_project": "chromium-reclient-metrics",'
-        '    "scandeps_server": true'
-        '  },'
-        '  "$build/siso": {'
-        '    "configs": [],'
-        '    "enable_cloud_profiler": true,'
-        '    "enable_cloud_trace": true,'
-        '    "experiments": [],'
-        '    "project": "rbe-chromium-untrusted"'
-        '  },'
-        '  "$recipe_engine/resultdb/test_presentation": {'
-        '    "column_keys": [],'
-        '    "grouping_keys": ['
-        '      "status",'
-        '      "v.test_suite"'
-        '    ]'
-        '  },'
-        '  "builder_group": "chromium.build",'
-        '  "recipe": "chrome_build/build_perf_developer"'
-        '}'
-      priority: 35
-      execution_timeout_secs: 36000
-      build_numbers: YES
-      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "chromium_swarming.expose_merge_script_failures"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-      description_html: "This builder measures build performance for Mac developer builds, by simulating developer build scenarios on a bot.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
-      shadow_builder_adjustments {
-        service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
-        pool: "luci.chromium.try"
-        dimensions: "builder:"
-        dimensions: "builderless:1"
-        dimensions: "pool:luci.chromium.try"
-      }
-    }
-    builders {
-      name: "mac-build-perf-siso"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builder:mac-build-perf-siso"
-      dimensions: "cpu:arm64"
-      dimensions: "os:Mac-13"
-      dimensions: "pool:luci.chromium.ci"
-      exe {
-        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
-        cipd_version: "refs/heads/main"
-        cmd: "luciexe"
-      }
-      properties:
-        '{'
-        '  "$build/chromium_tests_builder_config": {'
-        '    "builder_config": {'
-        '      "builder_db": {'
-        '        "entries": ['
-        '          {'
-        '            "builder_id": {'
-        '              "bucket": "ci",'
-        '              "builder": "mac-build-perf-siso",'
-        '              "project": "chromium"'
-        '            },'
-        '            "builder_spec": {'
-        '              "builder_group": "chromium.build",'
-        '              "execution_mode": "COMPILE_AND_TEST",'
-        '              "legacy_chromium_config": {'
-        '                "apply_configs": ['
-        '                  "mb"'
-        '                ],'
-        '                "build_config": "Release",'
-        '                "config": "chromium",'
-        '                "target_bits": 64,'
-        '                "target_platform": "mac"'
-        '              },'
-        '              "legacy_gclient_config": {'
-        '                "apply_configs": ['
-        '                  "siso_latest"'
-        '                ],'
-        '                "config": "chromium"'
-        '              }'
-        '            }'
-        '          }'
-        '        ]'
-        '      },'
-        '      "builder_ids": ['
-        '        {'
-        '          "bucket": "ci",'
-        '          "builder": "mac-build-perf-siso",'
-        '          "project": "chromium"'
-        '        }'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$build/code_coverage": {'
-        '    "use_clang_coverage": true'
-        '  },'
-        '  "$build/reclient": {'
-        '    "instance": "rbe-chromium-untrusted",'
-        '    "jobs": 500,'
-        '    "metrics_project": "chromium-reclient-metrics",'
-        '    "scandeps_server": true'
-        '  },'
-        '  "$build/siso": {'
-        '    "configs": ['
-        '      "builder"'
-        '    ],'
-        '    "enable_cloud_profiler": true,'
-        '    "enable_cloud_trace": true,'
-        '    "experiments": [],'
-        '    "project": "rbe-chromium-untrusted"'
-        '  },'
-        '  "$recipe_engine/resultdb/test_presentation": {'
-        '    "column_keys": [],'
-        '    "grouping_keys": ['
-        '      "status",'
-        '      "v.test_suite"'
-        '    ]'
-        '  },'
-        '  "builder_group": "chromium.build",'
-        '  "recipe": "chrome_build/build_perf_siso"'
-        '}'
-      priority: 35
-      execution_timeout_secs: 36000
-      build_numbers: YES
-      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "chromium_swarming.expose_merge_script_failures"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-      description_html: "This builder measures Mac build performance with Siso.<br/>The build configs and the bot specs should be in sync with <a href=\"https://ci.chromium.org/p/chromium/builders/try/mac-rel-compilator\">mac-rel-compilator</a>.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
-      shadow_builder_adjustments {
-        service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
-        pool: "luci.chromium.try"
-        properties:
-          '{'
-          '  "$build/reclient": {'
-          '    "instance": "rbe-chromium-untrusted",'
-          '    "jobs": 500,'
-          '    "metrics_project": "chromium-reclient-metrics",'
-          '    "scandeps_server": true'
-          '  }'
-          '}'
-        dimensions: "builder:"
-        dimensions: "builderless:1"
-        dimensions: "pool:luci.chromium.try"
-      }
-    }
-    builders {
       name: "mac-code-coverage"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
@@ -53420,134 +53438,6 @@
       contact_team_email: "chrome-sanitizer-builder-owners@google.com"
     }
     builders {
-      name: "win-build-perf-developer"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builder:win-build-perf-developer"
-      dimensions: "cpu:x86-64"
-      dimensions: "os:Windows-10"
-      dimensions: "pool:luci.chromium.ci"
-      exe {
-        cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build"
-        cipd_version: "refs/heads/main"
-        cmd: "luciexe"
-      }
-      properties:
-        '{'
-        '  "$build/chromium_tests_builder_config": {'
-        '    "builder_config": {'
-        '      "builder_db": {'
-        '        "entries": ['
-        '          {'
-        '            "builder_id": {'
-        '              "bucket": "ci",'
-        '              "builder": "win-build-perf-developer",'
-        '              "project": "chromium"'
-        '            },'
-        '            "builder_spec": {'
-        '              "builder_group": "chromium.build",'
-        '              "execution_mode": "COMPILE_AND_TEST",'
-        '              "legacy_chromium_config": {'
-        '                "apply_configs": ['
-        '                  "mb"'
-        '                ],'
-        '                "config": "chromium"'
-        '              },'
-        '              "legacy_gclient_config": {'
-        '                "apply_configs": ['
-        '                  "siso_latest"'
-        '                ],'
-        '                "config": "chromium"'
-        '              }'
-        '            }'
-        '          }'
-        '        ]'
-        '      },'
-        '      "builder_ids": ['
-        '        {'
-        '          "bucket": "ci",'
-        '          "builder": "win-build-perf-developer",'
-        '          "project": "chromium"'
-        '        }'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$build/reclient": {'
-        '    "instance": "rbe-chromium-untrusted",'
-        '    "jobs": 1000,'
-        '    "metrics_project": "chromium-reclient-metrics",'
-        '    "scandeps_server": true'
-        '  },'
-        '  "$build/siso": {'
-        '    "configs": [],'
-        '    "enable_cloud_profiler": true,'
-        '    "enable_cloud_trace": true,'
-        '    "experiments": [],'
-        '    "project": "rbe-chromium-untrusted"'
-        '  },'
-        '  "$recipe_engine/resultdb/test_presentation": {'
-        '    "column_keys": [],'
-        '    "grouping_keys": ['
-        '      "status",'
-        '      "v.test_suite"'
-        '    ]'
-        '  },'
-        '  "builder_group": "chromium.build",'
-        '  "recipe": "chrome_build/build_perf_developer"'
-        '}'
-      priority: 35
-      execution_timeout_secs: 36000
-      build_numbers: YES
-      service_account: "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "chromium_swarming.expose_merge_script_failures"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-      description_html: "This builder measures build performance for Windows developer builds, by simulating developer build scenarios on a high spec bot.<br>Build stats is show in http://shortn/_gaAdI3x6o6."
-      shadow_builder_adjustments {
-        service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
-        pool: "luci.chromium.try"
-        dimensions: "builder:"
-        dimensions: "builderless:1"
-        dimensions: "pool:luci.chromium.try"
-      }
-    }
-    builders {
       name: "win-celab-builder-rel"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builder:win-celab-builder-rel"
@@ -71492,6 +71382,98 @@
       description_html: "This builder mirrors the following CI builders:<br/><ul><li><a href=\"https://ci.chromium.org/p/chromium/builders/ci/chromeos-jacuzzi-rel\">chromeos-jacuzzi-rel</a></li></ul>"
     }
     builders {
+      name: "chromeos-jacuzzi-rel-skylab"
+      swarming_host: "chromium-swarm.appspot.com"
+      dimensions: "builderless:1"
+      dimensions: "cores:8"
+      dimensions: "cpu:x86-64"
+      dimensions: "os:Ubuntu-22.04"
+      dimensions: "pool:luci.chromium.try"
+      dimensions: "ssd:0"
+      exe {
+        cipd_package: "infra/chromium/bootstrapper/${platform}"
+        cipd_version: "latest"
+        cmd: "bootstrapper"
+      }
+      properties:
+        '{'
+        '  "$bootstrap/exe": {'
+        '    "exe": {'
+        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
+        '      "cipd_version": "refs/heads/main",'
+        '      "cmd": ['
+        '        "luciexe"'
+        '      ]'
+        '    }'
+        '  },'
+        '  "$bootstrap/properties": {'
+        '    "properties_file": "infra/config/generated/builders/try/chromeos-jacuzzi-rel-skylab/properties.json",'
+        '    "top_level_project": {'
+        '      "ref": "refs/heads/main",'
+        '      "repo": {'
+        '        "host": "chromium.googlesource.com",'
+        '        "project": "chromium/src"'
+        '      }'
+        '    }'
+        '  },'
+        '  "builder_group": "tryserver.chromium.chromiumos",'
+        '  "led_builder_is_bootstrapped": true,'
+        '  "recipe": "chromium_trybot"'
+        '}'
+      execution_timeout_secs: 14400
+      expiration_secs: 7200
+      grace_period {
+        seconds: 120
+      }
+      build_numbers: YES
+      service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
+      task_template_canary_percentage {
+        value: 5
+      }
+      experiments {
+        key: "chromium_swarming.expose_merge_script_failures"
+        value: 100
+      }
+      experiments {
+        key: "luci.recipes.use_python3"
+        value: 100
+      }
+      resultdb {
+        enable: true
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "try_test_results"
+          test_results {}
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "gpu_try_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
+            }
+          }
+        }
+        bq_exports {
+          project: "chrome-luci-data"
+          dataset: "chromium"
+          table: "blink_web_tests_try_test_results"
+          test_results {
+            predicate {
+              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)"
+            }
+          }
+        }
+        history_options {
+          use_invocation_timestamp: true
+        }
+      }
+      description_html: "This is a builder that runs HW test on Skylab. This builder also build Lacros with alternative toolchain.<br/>This builder mirrors the following CI builders:<br/><ul><li><a href=\"https://ci.chromium.org/p/chromium/builders/ci/chromeos-jacuzzi-rel-skylab-fyi\">chromeos-jacuzzi-rel-skylab-fyi</a></li></ul>"
+      contact_team_email: "chromeos-velocity@google.com"
+    }
+    builders {
       name: "chromeos-js-code-coverage"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg
index 97c3abea..7695c6fb 100644
--- a/infra/config/generated/luci/luci-milo.cfg
+++ b/infra/config/generated/luci/luci-milo.cfg
@@ -3095,6 +3095,9 @@
     name: "buildbucket/luci.chromium.try/chromeos-jacuzzi-rel"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/chromeos-jacuzzi-rel-skylab"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/chromeos-js-coverage-rel"
   }
   builders {
@@ -6235,72 +6238,72 @@
   refs: "regexp:refs/heads/main"
   manifest_name: "REVISION"
   builders {
-    name: "buildbucket/luci.chromium.ci/build-perf-android"
+    name: "buildbucket/luci.chromium.build/build-perf-android"
     category: "android"
     short_name: "ninja"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/build-perf-android-siso"
+    name: "buildbucket/luci.chromium.build/build-perf-android-siso"
     category: "android"
     short_name: "siso"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/build-perf-linux"
+    name: "buildbucket/luci.chromium.build/build-perf-linux"
     category: "linux"
     short_name: "ninja"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/build-perf-linux-siso"
+    name: "buildbucket/luci.chromium.build/build-perf-linux-siso"
     category: "linux"
     short_name: "siso"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/build-perf-windows"
+    name: "buildbucket/luci.chromium.build/build-perf-windows"
     category: "windows"
     short_name: "ninja"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/build-perf-windows-siso"
+    name: "buildbucket/luci.chromium.build/build-perf-windows-siso"
     category: "windows"
     short_name: "siso"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/linux-chromeos-build-perf"
+    name: "buildbucket/luci.chromium.build/linux-chromeos-build-perf"
     category: "cros"
     short_name: "ninja"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/linux-chromeos-build-perf-siso"
+    name: "buildbucket/luci.chromium.build/linux-chromeos-build-perf-siso"
     category: "cros"
     short_name: "siso"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/mac-build-perf"
+    name: "buildbucket/luci.chromium.build/mac-build-perf"
     category: "mac"
     short_name: "ninja"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/mac-build-perf-siso"
+    name: "buildbucket/luci.chromium.build/mac-build-perf-siso"
     category: "mac"
     short_name: "siso"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/android-build-perf-developer"
+    name: "buildbucket/luci.chromium.build/android-build-perf-developer"
     category: "android"
     short_name: "dev"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/linux-build-perf-developer"
+    name: "buildbucket/luci.chromium.build/linux-build-perf-developer"
     category: "linux"
     short_name: "dev"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/win-build-perf-developer"
+    name: "buildbucket/luci.chromium.build/win-build-perf-developer"
     category: "windows"
     short_name: "dev"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/mac-build-perf-developer"
+    name: "buildbucket/luci.chromium.build/mac-build-perf-developer"
     category: "mac"
     short_name: "dev"
   }
@@ -9394,6 +9397,11 @@
     short_name: "cmp"
   }
   builders {
+    name: "buildbucket/luci.chromium.ci/chromeos-jacuzzi-rel-skylab-fyi"
+    category: "ash"
+    short_name: "jcz"
+  }
+  builders {
     name: "buildbucket/luci.chromium.ci/win-celab-builder-rel"
     category: "celab"
   }
@@ -17264,6 +17272,9 @@
     name: "buildbucket/luci.chromium.try/chromeos-jacuzzi-rel"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/chromeos-jacuzzi-rel-skylab"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/chromeos-js-code-coverage"
   }
   builders {
@@ -18706,6 +18717,9 @@
     name: "buildbucket/luci.chromium.try/chromeos-jacuzzi-rel"
   }
   builders {
+    name: "buildbucket/luci.chromium.try/chromeos-jacuzzi-rel-skylab"
+  }
+  builders {
     name: "buildbucket/luci.chromium.try/chromeos-octopus-rel"
   }
   builders {
diff --git a/infra/config/generated/luci/luci-notify.cfg b/infra/config/generated/luci/luci-notify.cfg
index 8c53782..671561d 100644
--- a/infra/config/generated/luci/luci-notify.cfg
+++ b/infra/config/generated/luci/luci-notify.cfg
@@ -7,6 +7,188 @@
 notifiers {
   notifications {
     on_new_status: FAILURE
+    email {
+      recipients: "chrome-build-team+alert@google.com"
+    }
+  }
+  builders {
+    bucket: "build"
+    name: "android-build-perf-developer"
+    repository: "https://chromium.googlesource.com/chromium/src"
+  }
+}
+notifiers {
+  notifications {
+    on_new_status: FAILURE
+    email {
+      recipients: "chrome-build-team+alert@google.com"
+    }
+  }
+  builders {
+    bucket: "build"
+    name: "build-perf-android"
+    repository: "https://chromium.googlesource.com/chromium/src"
+  }
+}
+notifiers {
+  notifications {
+    on_new_status: FAILURE
+    email {
+      recipients: "chrome-build-team+alert@google.com"
+    }
+  }
+  builders {
+    bucket: "build"
+    name: "build-perf-android-siso"
+    repository: "https://chromium.googlesource.com/chromium/src"
+  }
+}
+notifiers {
+  notifications {
+    on_new_status: FAILURE
+    email {
+      recipients: "chrome-build-team+alert@google.com"
+    }
+  }
+  builders {
+    bucket: "build"
+    name: "build-perf-linux"
+    repository: "https://chromium.googlesource.com/chromium/src"
+  }
+}
+notifiers {
+  notifications {
+    on_new_status: FAILURE
+    email {
+      recipients: "chrome-build-team+alert@google.com"
+    }
+  }
+  builders {
+    bucket: "build"
+    name: "build-perf-linux-siso"
+    repository: "https://chromium.googlesource.com/chromium/src"
+  }
+}
+notifiers {
+  notifications {
+    on_new_status: FAILURE
+    email {
+      recipients: "chrome-build-team+alert@google.com"
+    }
+  }
+  builders {
+    bucket: "build"
+    name: "build-perf-windows"
+    repository: "https://chromium.googlesource.com/chromium/src"
+  }
+}
+notifiers {
+  notifications {
+    on_new_status: FAILURE
+    email {
+      recipients: "chrome-build-team+alert@google.com"
+    }
+  }
+  builders {
+    bucket: "build"
+    name: "build-perf-windows-siso"
+    repository: "https://chromium.googlesource.com/chromium/src"
+  }
+}
+notifiers {
+  notifications {
+    on_new_status: FAILURE
+    email {
+      recipients: "chrome-build-team+alert@google.com"
+    }
+  }
+  builders {
+    bucket: "build"
+    name: "linux-build-perf-developer"
+    repository: "https://chromium.googlesource.com/chromium/src"
+  }
+}
+notifiers {
+  notifications {
+    on_new_status: FAILURE
+    email {
+      recipients: "chrome-build-team+alert@google.com"
+    }
+  }
+  builders {
+    bucket: "build"
+    name: "linux-chromeos-build-perf"
+    repository: "https://chromium.googlesource.com/chromium/src"
+  }
+}
+notifiers {
+  notifications {
+    on_new_status: FAILURE
+    email {
+      recipients: "chrome-build-team+alert@google.com"
+    }
+  }
+  builders {
+    bucket: "build"
+    name: "linux-chromeos-build-perf-siso"
+    repository: "https://chromium.googlesource.com/chromium/src"
+  }
+}
+notifiers {
+  notifications {
+    on_new_status: FAILURE
+    email {
+      recipients: "chrome-build-team+alert@google.com"
+    }
+  }
+  builders {
+    bucket: "build"
+    name: "mac-build-perf"
+    repository: "https://chromium.googlesource.com/chromium/src"
+  }
+}
+notifiers {
+  notifications {
+    on_new_status: FAILURE
+    email {
+      recipients: "chrome-build-team+alert@google.com"
+    }
+  }
+  builders {
+    bucket: "build"
+    name: "mac-build-perf-developer"
+    repository: "https://chromium.googlesource.com/chromium/src"
+  }
+}
+notifiers {
+  notifications {
+    on_new_status: FAILURE
+    email {
+      recipients: "chrome-build-team+alert@google.com"
+    }
+  }
+  builders {
+    bucket: "build"
+    name: "mac-build-perf-siso"
+    repository: "https://chromium.googlesource.com/chromium/src"
+  }
+}
+notifiers {
+  notifications {
+    on_new_status: FAILURE
+    email {
+      recipients: "chrome-build-team+alert@google.com"
+    }
+  }
+  builders {
+    bucket: "build"
+    name: "win-build-perf-developer"
+    repository: "https://chromium.googlesource.com/chromium/src"
+  }
+}
+notifiers {
+  notifications {
+    on_new_status: FAILURE
     on_new_status: INFRA_FAILURE
     email {
       recipients: "chromium-infra+failures@google.com"
@@ -2014,19 +2196,6 @@
 notifiers {
   notifications {
     on_new_status: FAILURE
-    email {
-      recipients: "chrome-build-team+alert@google.com"
-    }
-  }
-  builders {
-    bucket: "ci"
-    name: "android-build-perf-developer"
-    repository: "https://chromium.googlesource.com/chromium/src"
-  }
-}
-notifiers {
-  notifications {
-    on_new_status: FAILURE
     on_new_status: INFRA_FAILURE
     on_new_status: SUCCESS
     email {
@@ -2518,84 +2687,6 @@
 }
 notifiers {
   notifications {
-    on_new_status: FAILURE
-    email {
-      recipients: "chrome-build-team+alert@google.com"
-    }
-  }
-  builders {
-    bucket: "ci"
-    name: "build-perf-android"
-    repository: "https://chromium.googlesource.com/chromium/src"
-  }
-}
-notifiers {
-  notifications {
-    on_new_status: FAILURE
-    email {
-      recipients: "chrome-build-team+alert@google.com"
-    }
-  }
-  builders {
-    bucket: "ci"
-    name: "build-perf-android-siso"
-    repository: "https://chromium.googlesource.com/chromium/src"
-  }
-}
-notifiers {
-  notifications {
-    on_new_status: FAILURE
-    email {
-      recipients: "chrome-build-team+alert@google.com"
-    }
-  }
-  builders {
-    bucket: "ci"
-    name: "build-perf-linux"
-    repository: "https://chromium.googlesource.com/chromium/src"
-  }
-}
-notifiers {
-  notifications {
-    on_new_status: FAILURE
-    email {
-      recipients: "chrome-build-team+alert@google.com"
-    }
-  }
-  builders {
-    bucket: "ci"
-    name: "build-perf-linux-siso"
-    repository: "https://chromium.googlesource.com/chromium/src"
-  }
-}
-notifiers {
-  notifications {
-    on_new_status: FAILURE
-    email {
-      recipients: "chrome-build-team+alert@google.com"
-    }
-  }
-  builders {
-    bucket: "ci"
-    name: "build-perf-windows"
-    repository: "https://chromium.googlesource.com/chromium/src"
-  }
-}
-notifiers {
-  notifications {
-    on_new_status: FAILURE
-    email {
-      recipients: "chrome-build-team+alert@google.com"
-    }
-  }
-  builders {
-    bucket: "ci"
-    name: "build-perf-windows-siso"
-    repository: "https://chromium.googlesource.com/chromium/src"
-  }
-}
-notifiers {
-  notifications {
     on_occurrence: FAILURE
     failed_step_regexp: "\\b(bot_update|compile|gclient runhooks|runhooks|update|\\w*nocompile_test)\\b"
     email {
@@ -3340,19 +3431,6 @@
 }
 notifiers {
   notifications {
-    on_new_status: FAILURE
-    email {
-      recipients: "chrome-build-team+alert@google.com"
-    }
-  }
-  builders {
-    bucket: "ci"
-    name: "linux-build-perf-developer"
-    repository: "https://chromium.googlesource.com/chromium/src"
-  }
-}
-notifiers {
-  notifications {
     on_occurrence: FAILURE
     failed_step_regexp: "\\b(bot_update|compile|gclient runhooks|runhooks|update|\\w*nocompile_test)\\b"
     email {
@@ -3372,32 +3450,6 @@
 }
 notifiers {
   notifications {
-    on_new_status: FAILURE
-    email {
-      recipients: "chrome-build-team+alert@google.com"
-    }
-  }
-  builders {
-    bucket: "ci"
-    name: "linux-chromeos-build-perf"
-    repository: "https://chromium.googlesource.com/chromium/src"
-  }
-}
-notifiers {
-  notifications {
-    on_new_status: FAILURE
-    email {
-      recipients: "chrome-build-team+alert@google.com"
-    }
-  }
-  builders {
-    bucket: "ci"
-    name: "linux-chromeos-build-perf-siso"
-    repository: "https://chromium.googlesource.com/chromium/src"
-  }
-}
-notifiers {
-  notifications {
     on_occurrence: FAILURE
     failed_step_regexp: "\\b(bot_update|compile|gclient runhooks|runhooks|update|\\w*nocompile_test)\\b"
     email {
@@ -3716,45 +3768,6 @@
 notifiers {
   notifications {
     on_new_status: FAILURE
-    email {
-      recipients: "chrome-build-team+alert@google.com"
-    }
-  }
-  builders {
-    bucket: "ci"
-    name: "mac-build-perf"
-    repository: "https://chromium.googlesource.com/chromium/src"
-  }
-}
-notifiers {
-  notifications {
-    on_new_status: FAILURE
-    email {
-      recipients: "chrome-build-team+alert@google.com"
-    }
-  }
-  builders {
-    bucket: "ci"
-    name: "mac-build-perf-developer"
-    repository: "https://chromium.googlesource.com/chromium/src"
-  }
-}
-notifiers {
-  notifications {
-    on_new_status: FAILURE
-    email {
-      recipients: "chrome-build-team+alert@google.com"
-    }
-  }
-  builders {
-    bucket: "ci"
-    name: "mac-build-perf-siso"
-    repository: "https://chromium.googlesource.com/chromium/src"
-  }
-}
-notifiers {
-  notifications {
-    on_new_status: FAILURE
     on_new_status: INFRA_FAILURE
     email {
       recipients: "chrome-rust-experiments+bots@google.com"
@@ -3875,19 +3888,6 @@
 notifiers {
   notifications {
     on_new_status: FAILURE
-    email {
-      recipients: "chrome-build-team+alert@google.com"
-    }
-  }
-  builders {
-    bucket: "ci"
-    name: "win-build-perf-developer"
-    repository: "https://chromium.googlesource.com/chromium/src"
-  }
-}
-notifiers {
-  notifications {
-    on_new_status: FAILURE
     on_new_status: INFRA_FAILURE
     email {
       recipients: "chrome-rust-experiments+bots@google.com"
diff --git a/infra/config/generated/luci/luci-scheduler.cfg b/infra/config/generated/luci/luci-scheduler.cfg
index d282190..0b27714 100644
--- a/infra/config/generated/luci/luci-scheduler.cfg
+++ b/infra/config/generated/luci/luci-scheduler.cfg
@@ -3350,10 +3350,10 @@
 }
 job {
   id: "android-build-perf-developer"
-  realm: "ci"
+  realm: "build"
   buildbucket {
     server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
+    bucket: "build"
     builder: "android-build-perf-developer"
   }
 }
@@ -3868,55 +3868,55 @@
 }
 job {
   id: "build-perf-android"
-  realm: "ci"
+  realm: "build"
   buildbucket {
     server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
+    bucket: "build"
     builder: "build-perf-android"
   }
 }
 job {
   id: "build-perf-android-siso"
-  realm: "ci"
+  realm: "build"
   buildbucket {
     server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
+    bucket: "build"
     builder: "build-perf-android-siso"
   }
 }
 job {
   id: "build-perf-linux"
-  realm: "ci"
+  realm: "build"
   buildbucket {
     server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
+    bucket: "build"
     builder: "build-perf-linux"
   }
 }
 job {
   id: "build-perf-linux-siso"
-  realm: "ci"
+  realm: "build"
   buildbucket {
     server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
+    bucket: "build"
     builder: "build-perf-linux-siso"
   }
 }
 job {
   id: "build-perf-windows"
-  realm: "ci"
+  realm: "build"
   buildbucket {
     server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
+    bucket: "build"
     builder: "build-perf-windows"
   }
 }
 job {
   id: "build-perf-windows-siso"
-  realm: "ci"
+  realm: "build"
   buildbucket {
     server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
+    bucket: "build"
     builder: "build-perf-windows-siso"
   }
 }
@@ -4065,6 +4065,15 @@
   }
 }
 job {
+  id: "chromeos-jacuzzi-rel-skylab-fyi"
+  realm: "ci"
+  buildbucket {
+    server: "cr-buildbucket.appspot.com"
+    bucket: "ci"
+    builder: "chromeos-jacuzzi-rel-skylab-fyi"
+  }
+}
+job {
   id: "chromeos-js-code-coverage"
   realm: "ci"
   schedule: "triggered"
@@ -4729,10 +4738,10 @@
 }
 job {
   id: "linux-build-perf-developer"
-  realm: "ci"
+  realm: "build"
   buildbucket {
     server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
+    bucket: "build"
     builder: "linux-build-perf-developer"
   }
 }
@@ -4765,19 +4774,19 @@
 }
 job {
   id: "linux-chromeos-build-perf"
-  realm: "ci"
+  realm: "build"
   buildbucket {
     server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
+    bucket: "build"
     builder: "linux-chromeos-build-perf"
   }
 }
 job {
   id: "linux-chromeos-build-perf-siso"
-  realm: "ci"
+  realm: "build"
   buildbucket {
     server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
+    bucket: "build"
     builder: "linux-chromeos-build-perf-siso"
   }
 }
@@ -5398,28 +5407,28 @@
 }
 job {
   id: "mac-build-perf"
-  realm: "ci"
+  realm: "build"
   buildbucket {
     server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
+    bucket: "build"
     builder: "mac-build-perf"
   }
 }
 job {
   id: "mac-build-perf-developer"
-  realm: "ci"
+  realm: "build"
   buildbucket {
     server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
+    bucket: "build"
     builder: "mac-build-perf-developer"
   }
 }
 job {
   id: "mac-build-perf-siso"
-  realm: "ci"
+  realm: "build"
   buildbucket {
     server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
+    bucket: "build"
     builder: "mac-build-perf-siso"
   }
 }
@@ -5858,10 +5867,10 @@
 }
 job {
   id: "win-build-perf-developer"
-  realm: "ci"
+  realm: "build"
   buildbucket {
     server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
+    bucket: "build"
     builder: "win-build-perf-developer"
   }
 }
@@ -6210,6 +6219,28 @@
   }
 }
 trigger {
+  id: "chrome-build-gitiles-trigger"
+  realm: "build"
+  triggers: "android-build-perf-developer"
+  triggers: "build-perf-android"
+  triggers: "build-perf-android-siso"
+  triggers: "build-perf-linux"
+  triggers: "build-perf-linux-siso"
+  triggers: "build-perf-windows"
+  triggers: "build-perf-windows-siso"
+  triggers: "linux-build-perf-developer"
+  triggers: "linux-chromeos-build-perf"
+  triggers: "linux-chromeos-build-perf-siso"
+  triggers: "mac-build-perf"
+  triggers: "mac-build-perf-developer"
+  triggers: "mac-build-perf-siso"
+  triggers: "win-build-perf-developer"
+  gitiles {
+    repo: "https://chromium.googlesource.com/chromium/src"
+    refs: "regexp:refs/heads/main"
+  }
+}
+trigger {
   id: "chromium-gitiles-trigger"
   realm: "ci"
   triggers: "ASAN Debug"
@@ -6406,7 +6437,6 @@
   triggers: "android-asan"
   triggers: "android-bfcache-rel"
   triggers: "android-binary-size-generator"
-  triggers: "android-build-perf-developer"
   triggers: "android-chrome-pie-x86-wpt-android-specific"
   triggers: "android-chrome-pie-x86-wpt-fyi-rel"
   triggers: "android-cronet-arm-dbg"
@@ -6436,12 +6466,6 @@
   triggers: "android-rust-arm64-rel"
   triggers: "android-webview-pie-x86-wpt-fyi-rel"
   triggers: "android-x86-rel"
-  triggers: "build-perf-android"
-  triggers: "build-perf-android-siso"
-  triggers: "build-perf-linux"
-  triggers: "build-perf-linux-siso"
-  triggers: "build-perf-windows"
-  triggers: "build-perf-windows-siso"
   triggers: "chromeos-amd64-generic-asan-rel"
   triggers: "chromeos-amd64-generic-cfi-thin-lto-rel"
   triggers: "chromeos-amd64-generic-dbg"
@@ -6454,6 +6478,7 @@
   triggers: "chromeos-arm-generic-rel"
   triggers: "chromeos-arm64-generic-rel"
   triggers: "chromeos-jacuzzi-rel"
+  triggers: "chromeos-jacuzzi-rel-skylab-fyi"
   triggers: "chromeos-octopus-rel"
   triggers: "fuchsia-angle-builder"
   triggers: "fuchsia-arm64-cast-receiver-rel"
@@ -6502,12 +6527,9 @@
   triggers: "linux-blink-heap-verification"
   triggers: "linux-blink-web-tests-force-accessibility-rel"
   triggers: "linux-blink-wpt-reset-rel"
-  triggers: "linux-build-perf-developer"
   triggers: "linux-cfm-rel"
   triggers: "linux-chromeos-annotator-rel"
   triggers: "linux-chromeos-archive-rel"
-  triggers: "linux-chromeos-build-perf"
-  triggers: "linux-chromeos-build-perf-siso"
   triggers: "linux-chromeos-dbg"
   triggers: "linux-chromeos-rel"
   triggers: "linux-extended-tracing-rel"
@@ -6551,9 +6573,6 @@
   triggers: "mac-arm64-dbg"
   triggers: "mac-arm64-on-arm64-rel"
   triggers: "mac-arm64-rel"
-  triggers: "mac-build-perf"
-  triggers: "mac-build-perf-developer"
-  triggers: "mac-build-perf-siso"
   triggers: "mac-intel-on-arm64-rel"
   triggers: "mac-official"
   triggers: "mac-osxbeta-rel"
@@ -6571,7 +6590,6 @@
   triggers: "win-annotator-rel"
   triggers: "win-archive-rel"
   triggers: "win-asan"
-  triggers: "win-build-perf-developer"
   triggers: "win-fieldtrial-rel"
   triggers: "win-official"
   triggers: "win-presubmit"
diff --git a/infra/config/generated/luci/realms.cfg b/infra/config/generated/luci/realms.cfg
index 066ee51b..e0a014f 100644
--- a/infra/config/generated/luci/realms.cfg
+++ b/infra/config/generated/luci/realms.cfg
@@ -84,11 +84,34 @@
   }
 }
 realms {
+  name: "build"
+  bindings {
+    role: "role/buildbucket.builderServiceAccount"
+    principals: "user:chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+  }
+  bindings {
+    role: "role/buildbucket.owner"
+    principals: "group:project-chromium-admins"
+  }
+  bindings {
+    role: "role/buildbucket.reader"
+    principals: "group:all"
+  }
+  bindings {
+    role: "role/buildbucket.triggerer"
+    principals: "group:mdb/foundry-x-team"
+    principals: "group:project-chromium-ci-schedulers"
+  }
+  bindings {
+    role: "role/scheduler.triggerer"
+    principals: "group:project-chromium-scheduler-triggerers"
+  }
+}
+realms {
   name: "ci"
   bindings {
     role: "role/buildbucket.builderServiceAccount"
     principals: "user:chromium-automated-expectation@chops-service-accounts.iam.gserviceaccount.com"
-    principals: "user:chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
     principals: "user:chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
     principals: "user:chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
     principals: "user:chromium-cipd-builder@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/infra/config/generated/testing/gn_isolate_map.pyl b/infra/config/generated/testing/gn_isolate_map.pyl
index 9c60acca..d5ecf1d 100644
--- a/infra/config/generated/testing/gn_isolate_map.pyl
+++ b/infra/config/generated/testing/gn_isolate_map.pyl
@@ -987,7 +987,7 @@
   },
   "keyboard_accessory_junit_tests": {
     "label": "//chrome/android/features/keyboard_accessory:keyboard_accessory_junit_tests",
-    "type": "junit_test",
+    "type": "generated_script",
   },
   "keyboard_unittests": {
     "label": "//ash/keyboard/ui:keyboard_unittests",
diff --git a/infra/config/generated/testing/variants.pyl b/infra/config/generated/testing/variants.pyl
index f47dcc27..232b261 100644
--- a/infra/config/generated/testing/variants.pyl
+++ b/infra/config/generated/testing/variants.pyl
@@ -70,16 +70,16 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'identifier': 'Lacros version skew testing ash canary',
-    'description': 'Run with ash-chrome version 121.0.6111.0',
+    'description': 'Run with ash-chrome version 121.0.6113.0',
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6111.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6113.0/test_ash_chrome',
     ],
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v121.0.6111.0',
-          'revision': 'version:121.0.6111.0',
+          'location': 'lacros_version_skew_tests_v121.0.6113.0',
+          'revision': 'version:121.0.6113.0',
         },
       ],
     },
@@ -620,7 +620,7 @@
     'identifier': 'EVE_PUBLIC_LKGM',
     'skylab': {
       'cros_board': 'eve',
-      'cros_img': 'eve-public/R121-15669.0.0',
+      'cros_img': 'eve-public/R121-15670.0.0',
       'bucket': 'chromiumos-image-archive',
       'dut_pool': 'chromium',
       'public_builder': 'cros_test_platform_public',
@@ -694,7 +694,7 @@
     'identifier': 'JACUZZI_PUBLIC_LKGM',
     'skylab': {
       'cros_board': 'jacuzzi',
-      'cros_img': 'jacuzzi-public/R121-15669.0.0',
+      'cros_img': 'jacuzzi-public/R121-15670.0.0',
       'bucket': 'chromiumos-image-archive',
     },
   },
@@ -702,7 +702,7 @@
     'identifier': 'JACUZZI_CQ_PUBLIC_LKGM',
     'skylab': {
       'cros_board': 'jacuzzi',
-      'cros_img': 'jacuzzi-public/R121-15669.0.0',
+      'cros_img': 'jacuzzi-public/R121-15670.0.0',
       'bucket': 'chromiumos-image-archive',
       'public_builder': 'cros_test_platform_public',
       'public_builder_bucket': 'testplatform-public',
@@ -712,7 +712,7 @@
     'identifier': 'TROGDOR_PUBLIC_LKGM',
     'skylab': {
       'cros_board': 'trogdor',
-      'cros_img': 'trogdor-public/R121-15669.0.0',
+      'cros_img': 'trogdor-public/R121-15670.0.0',
       'bucket': 'chromiumos-image-archive',
     },
   },
@@ -720,7 +720,7 @@
     'identifier': 'OCTOPUS_PUBLIC_LKGM',
     'skylab': {
       'cros_board': 'octopus',
-      'cros_img': 'octopus-public/R121-15669.0.0',
+      'cros_img': 'octopus-public/R121-15670.0.0',
       'bucket': 'chromiumos-image-archive',
     },
   },
@@ -799,7 +799,7 @@
     'skylab': {
       'cros_board': 'volteer',
       'cros_model': 'voxel',
-      'cros_img': 'volteer-public/R121-15669.0.0',
+      'cros_img': 'volteer-public/R121-15670.0.0',
       'bucket': 'chromiumos-image-archive',
       'dut_pool': 'chromium',
       'public_builder': 'cros_test_platform_public',
diff --git a/infra/config/lib/targets.star b/infra/config/lib/targets.star
index 791bcb5..9d8a6e5 100644
--- a/infra/config/lib/targets.star
+++ b/infra/config/lib/targets.star
@@ -117,23 +117,21 @@
         args = args,
     )
 
-def _junit_test(*, name, label, skip_usage_check = False):
+def _junit_test(*, name, label, skip_usage_check = False, args = None):
     """Define a junit test target to use in targets specs.
 
     A junit test target is a test using the JUnit test framework.
 
+    crbug/1401052: we're migrating these tests to isolated scripts,
+    but leaving the junit_tests defs around as documentation.
+
     Args:
         name: The name that can be used to refer to the target.
         label: The GN label for the ninja target.
         skip_usage_check: Disables checking that the target is actually
             referenced in a targets spec for some builder.
     """
-    _create_target(
-        name = name,
-        type = "junit_test",
-        label = label,
-        skip_usage_check = skip_usage_check,
-    )
+    _generated_script(name = name, label = label, skip_usage_check = skip_usage_check, args = args)
 
 def _script(*, name, label, script, skip_usage_check = False, args = None):
     """Define a script target to use in targets specs.
diff --git a/infra/config/main.star b/infra/config/main.star
index 40c3aa3e..83b94c2 100755
--- a/infra/config/main.star
+++ b/infra/config/main.star
@@ -256,8 +256,9 @@
 
 exec("//notifiers.star")
 
-exec("//subprojects/chromium/subproject.star")
+exec("//subprojects/build/subproject.star")
 exec("//subprojects/chrome/subproject.star")
+exec("//subprojects/chromium/subproject.star")
 exec("//subprojects/infra.star")
 branches.exec("//subprojects/codesearch/subproject.star")
 branches.exec("//subprojects/findit/subproject.star")
diff --git a/infra/config/subprojects/build/OWNERS b/infra/config/subprojects/build/OWNERS
new file mode 100644
index 0000000..989cdf2b
--- /dev/null
+++ b/infra/config/subprojects/build/OWNERS
@@ -0,0 +1 @@
+include ../../groups/chrome-build/OWNERS
diff --git a/infra/config/subprojects/build/README.md b/infra/config/subprojects/build/README.md
new file mode 100644
index 0000000..b30079e
--- /dev/null
+++ b/infra/config/subprojects/build/README.md
@@ -0,0 +1,3 @@
+Contains definitions for LUCI entities for Chrome Build performance monitoring.
+
+* build.star - Builders that collect Chrome build metrics.
diff --git a/infra/config/subprojects/chromium/ci/chromium.build.star b/infra/config/subprojects/build/build.star
similarity index 93%
rename from infra/config/subprojects/chromium/ci/chromium.build.star
rename to infra/config/subprojects/build/build.star
index f08bc0b..2ab2bf5 100644
--- a/infra/config/subprojects/chromium/ci/chromium.build.star
+++ b/infra/config/subprojects/build/build.star
@@ -1,24 +1,60 @@
 # 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.
-"""Definitions of builders in the chromium.build builder group."""
+"""Definitions of builders in `build` bucket."""
 
 load("//lib/builder_config.star", "builder_config")
 load("//lib/builders.star", "cpu", "os", "reclient", "siso")
 load("//lib/ci.star", "ci")
 load("//lib/consoles.star", "consoles")
+load("//project.star", "settings")
+
+luci.bucket(
+    name = "build",
+    acls = [
+        acl.entry(
+            roles = acl.BUILDBUCKET_READER,
+            groups = "all",
+        ),
+        acl.entry(
+            roles = acl.BUILDBUCKET_TRIGGERER,
+            groups = [
+                "project-chromium-ci-schedulers",
+                "mdb/foundry-x-team",
+            ],
+        ),
+        acl.entry(
+            roles = acl.BUILDBUCKET_OWNER,
+            groups = "project-chromium-admins",
+        ),
+        acl.entry(
+            roles = acl.SCHEDULER_TRIGGERER,
+            groups = "project-chromium-scheduler-triggerers",
+        ),
+    ],
+)
+
+luci.gitiles_poller(
+    name = "chrome-build-gitiles-trigger",
+    bucket = "build",
+    repo = "https://chromium.googlesource.com/chromium/src",
+    refs = [settings.ref],
+)
 
 ci.defaults.set(
+    bucket = "build",
+    triggered_by = ["chrome-build-gitiles-trigger"],
     builder_group = "chromium.build",
     pool = ci.DEFAULT_POOL,
     builderless = False,
     # rely on the builder dimension for the bot selection.
     cores = None,
+    build_numbers = True,
+    contact_team_email = "chrome-build-team@google.com",
     execution_timeout = 10 * time.hour,
     notifies = ["chrome-build-perf"],
     priority = ci.DEFAULT_FYI_PRIORITY,
     service_account = "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com",
-    shadow_service_account = ci.DEFAULT_SHADOW_SERVICE_ACCOUNT,
     siso_configs = [],
     siso_enable_cloud_profiler = True,
     siso_enable_cloud_trace = True,
diff --git a/infra/config/subprojects/build/subproject.star b/infra/config/subprojects/build/subproject.star
new file mode 100644
index 0000000..7ec803a
--- /dev/null
+++ b/infra/config/subprojects/build/subproject.star
@@ -0,0 +1,5 @@
+# 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.
+
+exec("./build.star")
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star
index 3201bf8..59a9cb7 100644
--- a/infra/config/subprojects/chromium/ci.star
+++ b/infra/config/subprojects/chromium/ci.star
@@ -193,7 +193,6 @@
 exec("./ci/chromium.android.star")
 exec("./ci/chromium.android.fyi.star")
 exec("./ci/chromium.angle.star")
-exec("./ci/chromium.build.star")
 exec("./ci/chromium.cft.star")
 exec("./ci/chromium.chromiumos.star")
 exec("./ci/chromium.clang.star")
diff --git a/infra/config/subprojects/chromium/ci/chromium.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fyi.star
index da0ca55a..f99e760 100644
--- a/infra/config/subprojects/chromium/ci/chromium.fyi.star
+++ b/infra/config/subprojects/chromium/ci/chromium.fyi.star
@@ -133,6 +133,47 @@
 )
 
 ci.builder(
+    name = "chromeos-jacuzzi-rel-skylab-fyi",
+    description_html = """\
+This builder builds public image and runs tests on DUTs in the lab.<br/>\
+This is experimental.
+""",
+    builder_spec = builder_config.builder_spec(
+        gclient_config = builder_config.gclient_config(
+            config = "chromium",
+            apply_configs = [
+                "chromeos",
+                "checkout_lacros_sdk",
+            ],
+        ),
+        chromium_config = builder_config.chromium_config(
+            config = "chromium",
+            apply_configs = [
+                "mb",
+            ],
+            build_config = builder_config.build_config.RELEASE,
+            target_arch = builder_config.target_arch.ARM,
+            target_bits = 32,
+            target_platform = builder_config.target_platform.CHROMEOS,
+            target_cros_boards = [
+                "jacuzzi",
+                "arm-generic",
+            ],
+        ),
+        skylab_upload_location = builder_config.skylab_upload_location(
+            gs_bucket = "chrome-test-builds",
+            gs_extra = "ash",
+        ),
+    ),
+    os = os.LINUX_DEFAULT,
+    console_view_entry = consoles.console_view_entry(
+        category = "ash",
+        short_name = "jcz",
+    ),
+    contact_team_email = "chromeos-velocity@google.com",
+)
+
+ci.builder(
     name = "lacros-amd64-generic-rel-fyi",
     builder_spec = builder_config.builder_spec(
         gclient_config = builder_config.gclient_config(
diff --git a/infra/config/subprojects/chromium/ci/chromium.infra.star b/infra/config/subprojects/chromium/ci/chromium.infra.star
index c6ab0ee54..bf5fccf 100644
--- a/infra/config/subprojects/chromium/ci/chromium.infra.star
+++ b/infra/config/subprojects/chromium/ci/chromium.infra.star
@@ -183,18 +183,8 @@
         short_name = "sdk",
     ),
     properties = {
-        # We still package part of build-tools;25.0.2 to support
-        # http://bit.ly/2KNUygZ
         "packages": [
             {
-                "sdk_package_name": "build-tools;25.0.2",
-                "cipd_yaml": "third_party/android_sdk/cipd/build-tools/25.0.2.yaml",
-            },
-            {
-                "sdk_package_name": "build-tools;33.0.0",
-                "cipd_yaml": "third_party/android_sdk/cipd/build-tools/33.0.0.yaml",
-            },
-            {
                 "sdk_package_name": "build-tools;34.0.0",
                 "cipd_yaml": "third_party/android_sdk/cipd/build-tools/34.0.0.yaml",
             },
@@ -207,30 +197,14 @@
                 "cipd_yaml": "third_party/android_sdk/cipd/emulator.yaml",
             },
             {
-                "sdk_package_name": "patcher;v4",
-                "cipd_yaml": "third_party/android_sdk/cipd/patcher/v4.yaml",
-            },
-            {
-                "sdk_package_name": "platforms;android-33",
-                "cipd_yaml": "third_party/android_sdk/cipd/platforms/android-33.yaml",
-            },
-            {
                 "sdk_package_name": "platforms;android-34",
                 "cipd_yaml": "third_party/android_sdk/cipd/platforms/android-34.yaml",
             },
             {
-                "sdk_package_name": "platforms;android-TiramisuPrivacySandbox",
-                "cipd_yaml": "third_party/android_sdk/cipd/platforms/android-TiramisuPrivacySandbox.yaml",
-            },
-            {
                 "sdk_package_name": "platform-tools",
                 "cipd_yaml": "third_party/android_sdk/cipd/platform-tools.yaml",
             },
             {
-                "sdk_package_name": "sources;android-31",
-                "cipd_yaml": "third_party/android_sdk/cipd/sources/android-31.yaml",
-            },
-            {
                 "sdk_package_name": "system-images;android-19;google_apis;x86",
                 "cipd_yaml": "third_party/android_sdk/cipd/system_images/android-19/google_apis/x86.yaml",
             },
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
index aadee76..9729acd 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
@@ -314,6 +314,18 @@
 )
 
 try_.builder(
+    name = "chromeos-jacuzzi-rel-skylab",
+    branch_selector = branches.selector.MAIN,
+    description_html = "This is a builder that runs HW test on Skylab." +
+                       " This builder also build Lacros with alternative toolchain.",
+    mirrors = [
+        "ci/chromeos-jacuzzi-rel-skylab-fyi",
+    ],
+    contact_team_email = "chromeos-velocity@google.com",
+    main_list_view = "try",
+)
+
+try_.builder(
     name = "chromeos-octopus-rel",
     branch_selector = branches.selector.CROS_LTS_BRANCHES,
     mirrors = [
diff --git a/infra/config/targets/cros-skylab-variants.json b/infra/config/targets/cros-skylab-variants.json
index dd903df3..187e2e42 100644
--- a/infra/config/targets/cros-skylab-variants.json
+++ b/infra/config/targets/cros-skylab-variants.json
@@ -201,8 +201,8 @@
   "CROS_EVE_PUBLIC_LKGM": {
     "skylab": {
       "cros_board": "eve",
-      "cros_chrome_version": "121.0.6107.0",
-      "cros_img": "eve-public/R121-15669.0.0",
+      "cros_chrome_version": "121.0.6109.0",
+      "cros_img": "eve-public/R121-15670.0.0",
       "bucket": "chromiumos-image-archive",
       "dut_pool": "chromium",
       "public_builder": "cros_test_platform_public",
@@ -291,8 +291,8 @@
   "CROS_JACUZZI_PUBLIC_LKGM": {
     "skylab": {
       "cros_board": "jacuzzi",
-      "cros_chrome_version": "121.0.6107.0",
-      "cros_img": "jacuzzi-public/R121-15669.0.0",
+      "cros_chrome_version": "121.0.6109.0",
+      "cros_img": "jacuzzi-public/R121-15670.0.0",
       "bucket": "chromiumos-image-archive"
     },
     "enabled": true,
@@ -301,8 +301,8 @@
   "CROS_JACUZZI_CQ_PUBLIC_LKGM": {
     "skylab": {
       "cros_board": "jacuzzi",
-      "cros_chrome_version": "121.0.6107.0",
-      "cros_img": "jacuzzi-public/R121-15669.0.0",
+      "cros_chrome_version": "121.0.6109.0",
+      "cros_img": "jacuzzi-public/R121-15670.0.0",
       "bucket": "chromiumos-image-archive",
       "public_builder": "cros_test_platform_public",
       "public_builder_bucket": "testplatform-public"
@@ -313,8 +313,8 @@
   "CROS_TROGDOR_PUBLIC_LKGM": {
     "skylab": {
       "cros_board": "trogdor",
-      "cros_chrome_version": "121.0.6107.0",
-      "cros_img": "trogdor-public/R121-15669.0.0",
+      "cros_chrome_version": "121.0.6109.0",
+      "cros_img": "trogdor-public/R121-15670.0.0",
       "bucket": "chromiumos-image-archive"
     },
     "enabled": true,
@@ -323,8 +323,8 @@
   "CROS_OCTOPUS_PUBLIC_LKGM": {
     "skylab": {
       "cros_board": "octopus",
-      "cros_chrome_version": "121.0.6107.0",
-      "cros_img": "octopus-public/R121-15669.0.0",
+      "cros_chrome_version": "121.0.6109.0",
+      "cros_img": "octopus-public/R121-15670.0.0",
       "bucket": "chromiumos-image-archive"
     },
     "enabled": true,
@@ -418,8 +418,8 @@
     "skylab": {
       "cros_board": "volteer",
       "cros_model": "voxel",
-      "cros_chrome_version": "121.0.6107.0",
-      "cros_img": "volteer-public/R121-15669.0.0",
+      "cros_chrome_version": "121.0.6109.0",
+      "cros_img": "volteer-public/R121-15670.0.0",
       "bucket": "chromiumos-image-archive",
       "dut_pool": "chromium",
       "public_builder": "cros_test_platform_public",
diff --git a/infra/config/targets/lacros-version-skew-variants.json b/infra/config/targets/lacros-version-skew-variants.json
index 0ca97b4d..08cd1d1f 100644
--- a/infra/config/targets/lacros-version-skew-variants.json
+++ b/infra/config/targets/lacros-version-skew-variants.json
@@ -1,16 +1,16 @@
 {
   "LACROS_VERSION_SKEW_CANARY": {
     "args": [
-      "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6111.0/test_ash_chrome"
+      "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6113.0/test_ash_chrome"
     ],
-    "description": "Run with ash-chrome version 121.0.6111.0",
+    "description": "Run with ash-chrome version 121.0.6113.0",
     "identifier": "Lacros version skew testing ash canary",
     "swarming": {
       "cipd_packages": [
         {
           "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-          "location": "lacros_version_skew_tests_v121.0.6111.0",
-          "revision": "version:121.0.6111.0"
+          "location": "lacros_version_skew_tests_v121.0.6113.0",
+          "revision": "version:121.0.6113.0"
         }
       ]
     }
diff --git a/internal b/internal
index d03e9b6..95496ca 160000
--- a/internal
+++ b/internal
@@ -1 +1 @@
-Subproject commit d03e9b687fa3fb8a7deb59711777a7947b21252c
+Subproject commit 95496cacbb6d27a923918e1b7c1ef143b79c45b5
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn
index 7350de7..7a401b8 100644
--- a/ios/chrome/app/BUILD.gn
+++ b/ios/chrome/app/BUILD.gn
@@ -377,9 +377,9 @@
     "//ios/chrome/app/application_delegate:observing_app_state_agent",
     "//ios/chrome/browser/discover_feed:discover_feed",
     "//ios/chrome/browser/discover_feed:discover_feed_factory",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/shared/model/application_context",
     "//ios/chrome/browser/shared/model/browser_state",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/signin",
     "//ios/chrome/browser/ui/ntp/metrics",
     "//ios/chrome/browser/ui/ntp/metrics:constants",
@@ -491,7 +491,6 @@
     "//ios/chrome/browser/memory/model",
     "//ios/chrome/browser/metrics",
     "//ios/chrome/browser/metrics:metrics_internal",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/omaha",
     "//ios/chrome/browser/passwords/model",
     "//ios/chrome/browser/promos_manager:factory",
diff --git a/ios/chrome/app/application_delegate/BUILD.gn b/ios/chrome/app/application_delegate/BUILD.gn
index 8ced738..18b60a0d 100644
--- a/ios/chrome/app/application_delegate/BUILD.gn
+++ b/ios/chrome/app/application_delegate/BUILD.gn
@@ -28,12 +28,10 @@
     "metrics_mediator_unittest.mm",
     "url_opener_params_unittest.mm",
     "url_opener_unittest.mm",
-    "user_activity_handler_unittest.mm",
   ]
   deps = [
     ":application_delegate",
     ":application_delegate_internal",
-    ":constants",
     ":metric_kit_subscriber",
     ":tab_opening",
     ":test_support",
@@ -42,24 +40,16 @@
     "//base/test:test_support",
     "//components/crash/core/app",
     "//components/crash/core/common:reporter_running_ios",
-    "//components/handoff",
     "//components/metrics",
-    "//components/policy/core/common:common_constants",
-    "//components/prefs:test_support",
     "//components/previous_session_info",
     "//ios/chrome/app",
-    "//ios/chrome/app:app_internal",
     "//ios/chrome/app:enterprise_app_agent",
-    "//ios/chrome/app:mode",
     "//ios/chrome/app:safe_mode_app_state_agent",
-    "//ios/chrome/app/spotlight",
     "//ios/chrome/app/startup",
     "//ios/chrome/browser/crash_report/model",
     "//ios/chrome/browser/device_sharing",
-    "//ios/chrome/browser/flags:system_flags",
     "//ios/chrome/browser/geolocation/model",
     "//ios/chrome/browser/metrics",
-    "//ios/chrome/browser/policy:policy_util",
     "//ios/chrome/browser/shared/coordinator/scene",
     "//ios/chrome/browser/shared/coordinator/scene/test",
     "//ios/chrome/browser/shared/model/application_context",
@@ -80,7 +70,6 @@
     "//ios/chrome/browser/url_loading/model",
     "//ios/chrome/common/app_group",
     "//ios/chrome/common/crash_report",
-    "//ios/chrome/common/intents",
     "//ios/chrome/test:test_support",
     "//ios/chrome/test/providers/app_distribution",
     "//ios/public/provider/chrome/browser/app_distribution:app_distribution_api",
@@ -177,12 +166,9 @@
     "metrics_mediator.mm",
     "url_opener.h",
     "url_opener.mm",
-    "user_activity_handler.h",
-    "user_activity_handler.mm",
   ]
   deps = [
     ":application_delegate",
-    ":constants",
     ":metric_kit_subscriber",
     ":tab_opening",
     ":url_opener_params",
@@ -190,32 +176,24 @@
     "//build:branding_buildflags",
     "//components/crash/core/common",
     "//components/feature_engagement",
-    "//components/handoff",
     "//components/metrics",
-    "//components/prefs",
     "//components/previous_session_info",
-    "//components/search_engines",
     "//components/ukm/ios:ukm_reporting_ios_util",
     "//ios/chrome/app",
-    "//ios/chrome/app:mode",
-    "//ios/chrome/app/spotlight",
     "//ios/chrome/app/startup",
     "//ios/chrome/app/startup:ios_enable_sandbox_dump_buildflags",
-    "//ios/chrome/app/startup:startup_basic",
     "//ios/chrome/browser/browsing_data/model",
     "//ios/chrome/browser/crash_report/model",
     "//ios/chrome/browser/default_browser/model:utils",
     "//ios/chrome/browser/device_sharing",
     "//ios/chrome/browser/feature_engagement/model",
     "//ios/chrome/browser/geolocation/model",
-    "//ios/chrome/browser/intents:intent_type",
     "//ios/chrome/browser/metrics",
     "//ios/chrome/browser/metrics:metrics_internal",
     "//ios/chrome/browser/metrics/model",
     "//ios/chrome/browser/ntp:util",
     "//ios/chrome/browser/ntp/home:features",
     "//ios/chrome/browser/policy:policy_util",
-    "//ios/chrome/browser/search_engines/model",
     "//ios/chrome/browser/shared/coordinator/scene",
     "//ios/chrome/browser/shared/model/application_context",
     "//ios/chrome/browser/shared/model/browser",
@@ -239,7 +217,6 @@
     "//ios/chrome/common/app_group",
     "//ios/chrome/common/app_group:main_app",
     "//ios/chrome/common/credential_provider",
-    "//ios/chrome/common/intents",
     "//ios/net",
     "//ios/public/provider/chrome/browser/app_distribution:app_distribution_api",
     "//ios/public/provider/chrome/browser/user_feedback:user_feedback_api",
@@ -263,13 +240,6 @@
   ]
 }
 
-source_set("constants") {
-  sources = [
-    "intents_constants.h",
-    "intents_constants.mm",
-  ]
-}
-
 source_set("test_support") {
   testonly = true
   sources = [
diff --git a/ios/chrome/app/application_delegate/app_state.mm b/ios/chrome/app/application_delegate/app_state.mm
index 430387e..857b265 100644
--- a/ios/chrome/app/application_delegate/app_state.mm
+++ b/ios/chrome/app/application_delegate/app_state.mm
@@ -24,7 +24,6 @@
 #import "ios/chrome/app/application_delegate/memory_warning_helper.h"
 #import "ios/chrome/app/application_delegate/metrics_mediator.h"
 #import "ios/chrome/app/application_delegate/startup_information.h"
-#import "ios/chrome/app/application_delegate/user_activity_handler.h"
 #import "ios/chrome/app/deferred_initialization_runner.h"
 #import "ios/chrome/browser/browsing_data/model/sessions_storage_util.h"
 #import "ios/chrome/browser/crash_report/model/crash_helper.h"
@@ -34,7 +33,6 @@
 #import "ios/chrome/browser/device_sharing/device_sharing_manager.h"
 #import "ios/chrome/browser/feature_engagement/model/tracker_factory.h"
 #import "ios/chrome/browser/metrics/model/web_state_list_metrics_browser_agent.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/shared/coordinator/scene/scene_delegate.h"
 #import "ios/chrome/browser/shared/model/application_context/application_context.h"
 #import "ios/chrome/browser/shared/model/browser/browser.h"
@@ -45,6 +43,7 @@
 #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
 #import "ios/chrome/browser/shared/public/commands/help_commands.h"
 #import "ios/chrome/browser/shared/public/commands/open_new_tab_command.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/signin/authentication_service.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/signin/system_identity_manager.h"
diff --git a/ios/chrome/app/application_delegate/app_state_unittest.mm b/ios/chrome/app/application_delegate/app_state_unittest.mm
index 3e81457..f202529 100644
--- a/ios/chrome/app/application_delegate/app_state_unittest.mm
+++ b/ios/chrome/app/application_delegate/app_state_unittest.mm
@@ -19,7 +19,6 @@
 #import "ios/chrome/app/application_delegate/metrics_mediator.h"
 #import "ios/chrome/app/application_delegate/mock_tab_opener.h"
 #import "ios/chrome/app/application_delegate/startup_information.h"
-#import "ios/chrome/app/application_delegate/user_activity_handler.h"
 #import "ios/chrome/app/enterprise_app_agent.h"
 #import "ios/chrome/app/safe_mode_app_state_agent+private.h"
 #import "ios/chrome/app/safe_mode_app_state_agent.h"
@@ -128,14 +127,6 @@
 
 // A block that takes self as argument and return a BOOL.
 typedef BOOL (^DecisionBlock)(id self);
-// A block that takes the arguments of UserActivityHandler's
-// +handleStartupParametersWithTabOpener.
-typedef void (^HandleStartupParam)(
-    id self,
-    id<TabOpening> tabOpener,
-    id<ConnectionInformation> connectionInformation,
-    id<StartupInformation> startupInformation,
-    ChromeBrowserState* browserState);
 // A block ths returns values of AppState connectedScenes.
 typedef NSArray<SceneState*>* (^ScenesBlock)(id self);
 
@@ -229,28 +220,6 @@
         safe_mode_swizzle_block_));
   }
 
-  void SwizzleHandleStartupParameters(
-      id<TabOpening> expectedTabOpener,
-      ChromeBrowserState* expectedBrowserState) {
-    handle_startup_swizzle_block_ =
-        ^(id self, id<TabOpening> tabOpener,
-          id<ConnectionInformation> connectionInformation,
-          id<StartupInformation> startupInformation,
-          ChromeBrowserState* browserState) {
-          ASSERT_EQ(connection_information_mock_, connectionInformation);
-          ASSERT_EQ(startup_information_mock_, startupInformation);
-          ASSERT_EQ(expectedTabOpener, tabOpener);
-          ASSERT_EQ(expectedBrowserState, browserState);
-        };
-
-    handle_startup_swizzler_.reset(new ScopedBlockSwizzler(
-        [UserActivityHandler class],
-        @selector(handleStartupParametersWithTabOpener:
-                                 connectionInformation:startupInformation
-                                                      :browserState:initStage:),
-        handle_startup_swizzle_block_));
-  }
-
   SafeModeAppAgent* GetSafeModeAppAgent() {
     if (!safe_mode_app_agent_) {
       safe_mode_app_agent_ = [[SafeModeAppAgent alloc] init];
@@ -362,7 +331,6 @@
   StubBrowserProviderInterface* provider_interface_;
   ScenesBlock connected_scenes_swizzle_block_;
   DecisionBlock safe_mode_swizzle_block_;
-  HandleStartupParam handle_startup_swizzle_block_;
   std::unique_ptr<ScopedBlockSwizzler> safe_mode_swizzler_;
   std::unique_ptr<ScopedBlockSwizzler> connected_scenes_swizzler_;
   std::unique_ptr<ScopedBlockSwizzler> handle_startup_swizzler_;
diff --git a/ios/chrome/app/feed_app_agent.mm b/ios/chrome/app/feed_app_agent.mm
index 1bf46b417..c357a476 100644
--- a/ios/chrome/app/feed_app_agent.mm
+++ b/ios/chrome/app/feed_app_agent.mm
@@ -12,8 +12,8 @@
 #import "ios/chrome/browser/discover_feed/discover_feed_service.h"
 #import "ios/chrome/browser/discover_feed/discover_feed_service_factory.h"
 #import "ios/chrome/browser/discover_feed/feed_constants.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/shared/model/application_context/application_context.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/signin/authentication_service.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.h"
diff --git a/ios/chrome/app/main_application_delegate.mm b/ios/chrome/app/main_application_delegate.mm
index 2274179..1cdd0ec 100644
--- a/ios/chrome/app/main_application_delegate.mm
+++ b/ios/chrome/app/main_application_delegate.mm
@@ -20,7 +20,6 @@
 #import "ios/chrome/app/application_delegate/startup_information.h"
 #import "ios/chrome/app/application_delegate/url_opener.h"
 #import "ios/chrome/app/application_delegate/url_opener_params.h"
-#import "ios/chrome/app/application_delegate/user_activity_handler.h"
 #import "ios/chrome/app/chrome_overlay_window.h"
 #import "ios/chrome/app/main_application_delegate_testing.h"
 #import "ios/chrome/app/main_controller.h"
diff --git a/ios/chrome/app/post_restore_app_agent_unittest.mm b/ios/chrome/app/post_restore_app_agent_unittest.mm
index 4d693b13..0cbabc2d 100644
--- a/ios/chrome/app/post_restore_app_agent_unittest.mm
+++ b/ios/chrome/app/post_restore_app_agent_unittest.mm
@@ -87,7 +87,8 @@
   void SetFakePreRestoreAccountInfo() {
     AccountInfo accountInfo;
     accountInfo.email = kFakePreRestoreAccountEmail;
-    StorePreRestoreIdentity(local_state_.Get(), accountInfo);
+    StorePreRestoreIdentity(local_state_.Get(), accountInfo,
+                            /*history_sync_enabled=*/false);
   }
 
   // Signs in a fake identity.
diff --git a/ios/chrome/browser/default_browser/model/BUILD.gn b/ios/chrome/browser/default_browser/model/BUILD.gn
index 542e033..abe77b2 100644
--- a/ios/chrome/browser/default_browser/model/BUILD.gn
+++ b/ios/chrome/browser/default_browser/model/BUILD.gn
@@ -17,7 +17,6 @@
     "//components/feature_engagement/public",
     "//components/sync/service",
     "//ios/chrome/browser/feature_engagement/model",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/settings/model/sync/utils:identity_error_util",
     "//ios/chrome/browser/shared/model/application_context",
     "//ios/chrome/browser/shared/public/features",
diff --git a/ios/chrome/browser/default_browser/model/utils.mm b/ios/chrome/browser/default_browser/model/utils.mm
index 3742f5b..c256c04 100644
--- a/ios/chrome/browser/default_browser/model/utils.mm
+++ b/ios/chrome/browser/default_browser/model/utils.mm
@@ -19,7 +19,6 @@
 #import "components/feature_engagement/public/tracker.h"
 #import "components/sync/service/sync_service.h"
 #import "ios/chrome/browser/feature_engagement/model/tracker_factory.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/settings/model/sync/utils/identity_error_util.h"
 #import "ios/chrome/browser/shared/model/application_context/application_context.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
diff --git a/ios/chrome/browser/flags/BUILD.gn b/ios/chrome/browser/flags/BUILD.gn
index 63676649..62e3e0739 100644
--- a/ios/chrome/browser/flags/BUILD.gn
+++ b/ios/chrome/browser/flags/BUILD.gn
@@ -65,7 +65,6 @@
     "//ios/chrome/browser/find_in_page/model:util",
     "//ios/chrome/browser/follow:feature_flags",
     "//ios/chrome/browser/iph_for_new_chrome_user/model",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/ntp/home:features",
     "//ios/chrome/browser/parcel_tracking:features",
     "//ios/chrome/browser/policy",
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm
index fca69442..a6173a7 100644
--- a/ios/chrome/browser/flags/about_flags.mm
+++ b/ios/chrome/browser/flags/about_flags.mm
@@ -78,8 +78,6 @@
 #import "ios/chrome/browser/flags/ios_chrome_flag_descriptions.h"
 #import "ios/chrome/browser/follow/follow_features.h"
 #import "ios/chrome/browser/iph_for_new_chrome_user/model/features.h"
-#import "ios/chrome/browser/ntp/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/parcel_tracking/features.h"
 #import "ios/chrome/browser/policy/cloud/user_policy_constants.h"
 #import "ios/chrome/browser/policy/policy_util.h"
diff --git a/ios/chrome/browser/follow/BUILD.gn b/ios/chrome/browser/follow/BUILD.gn
index fbce92d..4a437d8 100644
--- a/ios/chrome/browser/follow/BUILD.gn
+++ b/ios/chrome/browser/follow/BUILD.gn
@@ -27,9 +27,9 @@
   deps = [
     ":enums",
     "//components/prefs",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/shared/model/browser_state",
     "//ios/chrome/browser/shared/model/prefs:pref_names",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/signin",
     "//ios/web/public",
     "//url",
@@ -65,9 +65,9 @@
     "//ios/chrome/browser/follow:enums",
     "//ios/chrome/browser/follow:utils",
     "//ios/chrome/browser/history",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/shared/model/browser_state",
     "//ios/chrome/browser/shared/model/url",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/shared/public/features:system_flags",
     "//ios/chrome/browser/signin",
     "//ios/web/public",
@@ -130,11 +130,11 @@
     "//ios/chrome/browser/follow:service",
     "//ios/chrome/browser/follow:service_factory",
     "//ios/chrome/browser/net:crurl",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/shared/model/browser",
     "//ios/chrome/browser/shared/model/browser_state",
     "//ios/chrome/browser/shared/model/prefs:pref_names",
     "//ios/chrome/browser/shared/public/commands",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/shared/public/features:system_flags",
     "//ios/chrome/browser/ui/follow",
     "//ios/chrome/browser/ui/ntp/metrics",
diff --git a/ios/chrome/browser/follow/DEPS b/ios/chrome/browser/follow/DEPS
index 983f4a11..1de74bf 100644
--- a/ios/chrome/browser/follow/DEPS
+++ b/ios/chrome/browser/follow/DEPS
@@ -2,7 +2,6 @@
   "+ios/chrome/browser/discover_feed",
   "+ios/chrome/browser/feature_engagement/model",
   "+ios/chrome/browser/history",
-  "+ios/chrome/browser/ntp/features.h",
   "+ios/chrome/browser/signin",
 ]
 
diff --git a/ios/chrome/browser/follow/follow_browser_agent.mm b/ios/chrome/browser/follow/follow_browser_agent.mm
index 5ec4e57..aca3572 100644
--- a/ios/chrome/browser/follow/follow_browser_agent.mm
+++ b/ios/chrome/browser/follow/follow_browser_agent.mm
@@ -18,13 +18,13 @@
 #import "ios/chrome/browser/follow/follow_service.h"
 #import "ios/chrome/browser/follow/follow_service_factory.h"
 #import "ios/chrome/browser/follow/web_page_urls.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/shared/model/browser/browser.h"
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/shared/model/prefs/pref_names.h"
 #import "ios/chrome/browser/shared/public/commands/feed_commands.h"
 #import "ios/chrome/browser/shared/public/commands/new_tab_page_commands.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/features/system_flags.h"
 #import "ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.h"
 #import "ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.h"
diff --git a/ios/chrome/browser/follow/follow_tab_helper.mm b/ios/chrome/browser/follow/follow_tab_helper.mm
index 09fa65b..ec1d6ce7 100644
--- a/ios/chrome/browser/follow/follow_tab_helper.mm
+++ b/ios/chrome/browser/follow/follow_tab_helper.mm
@@ -28,9 +28,9 @@
 #import "ios/chrome/browser/follow/follow_service_factory.h"
 #import "ios/chrome/browser/follow/follow_util.h"
 #import "ios/chrome/browser/history/history_service_factory.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/shared/model/url/url_util.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/public/features/system_flags.h"
 #import "ios/chrome/browser/signin/authentication_service.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
diff --git a/ios/chrome/browser/follow/follow_util.mm b/ios/chrome/browser/follow/follow_util.mm
index 3326956..e1ea60c 100644
--- a/ios/chrome/browser/follow/follow_util.mm
+++ b/ios/chrome/browser/follow/follow_util.mm
@@ -7,9 +7,9 @@
 #import <UIKit/UIKit.h>
 
 #import "components/prefs/pref_service.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/shared/model/prefs/pref_names.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/signin/authentication_service.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/web/public/web_client.h"
diff --git a/ios/chrome/browser/intents/BUILD.gn b/ios/chrome/browser/intents/BUILD.gn
index 253e48c..6985e9d 100644
--- a/ios/chrome/browser/intents/BUILD.gn
+++ b/ios/chrome/browser/intents/BUILD.gn
@@ -21,3 +21,80 @@
 source_set("intent_type") {
   sources = [ "intent_type.h" ]
 }
+
+source_set("constants") {
+  sources = [
+    "intents_constants.h",
+    "intents_constants.mm",
+  ]
+}
+
+source_set("user_activity_handler") {
+  sources = [
+    "user_activity_handler.h",
+    "user_activity_handler.mm",
+  ]
+
+  public_deps = [ "//ios/chrome/browser/shared/model/browser" ]
+  deps = [
+    ":constants",
+    "//base",
+    "//components/crash/core/common",
+    "//components/handoff",
+    "//components/prefs",
+    "//components/search_engines",
+    "//ios/chrome/app",
+    "//ios/chrome/app:mode",
+    "//ios/chrome/app/application_delegate:app_state_header",
+    "//ios/chrome/app/application_delegate:tab_opening",
+    "//ios/chrome/app/spotlight",
+    "//ios/chrome/app/startup",
+    "//ios/chrome/app/startup:startup_basic",
+    "//ios/chrome/browser/intents:intent_type",
+    "//ios/chrome/browser/metrics:metrics_internal",
+    "//ios/chrome/browser/policy:policy_util",
+    "//ios/chrome/browser/search_engines/model",
+    "//ios/chrome/browser/shared/coordinator/scene:scene_state_header",
+    "//ios/chrome/browser/shared/model/browser_state",
+    "//ios/chrome/browser/shared/model/url:constants",
+    "//ios/chrome/browser/url_loading/model",
+    "//ios/chrome/browser/url_loading/model:url_loading_params_header",
+    "//ios/chrome/common/intents:intents_generate_source",
+    "//ui/base",
+    "//url",
+  ]
+}
+
+source_set("unit_tests") {
+  testonly = true
+  sources = [ "user_activity_handler_unittest.mm" ]
+  deps = [
+    ":constants",
+    ":user_activity_handler",
+    "//components/handoff",
+    "//components/policy/core/common:common_constants",
+    "//components/prefs",
+    "//components/prefs:test_support",
+    "//ios/chrome/app",
+    "//ios/chrome/app:app_internal",
+    "//ios/chrome/app:mode",
+    "//ios/chrome/app/application_delegate:app_state_header",
+    "//ios/chrome/app/application_delegate:test_support",
+    "//ios/chrome/app/spotlight",
+    "//ios/chrome/browser/flags:system_flags",
+    "//ios/chrome/browser/policy:policy_util",
+    "//ios/chrome/browser/shared/coordinator/scene:scene_state_header",
+    "//ios/chrome/browser/shared/coordinator/scene/test",
+    "//ios/chrome/browser/shared/model/browser/test:test_support",
+    "//ios/chrome/browser/shared/model/browser_state:test_support",
+    "//ios/chrome/browser/shared/model/url:constants",
+    "//ios/chrome/browser/shared/public/features",
+    "//ios/chrome/browser/url_loading/model",
+    "//ios/chrome/common/intents",
+    "//ios/testing:block_swizzler",
+    "//ios/web/public/test",
+    "//net:gtest_util",
+    "//testing/gtest",
+    "//third_party/ocmock",
+  ]
+}
diff --git a/ios/chrome/browser/intents/DEPS b/ios/chrome/browser/intents/DEPS
new file mode 100644
index 0000000..7011482
--- /dev/null
+++ b/ios/chrome/browser/intents/DEPS
@@ -0,0 +1,7 @@
+include_rules = [
+  "+ios/chrome/browser/metrics",
+  "+ios/chrome/browser/policy",
+  "+ios/chrome/browser/search_engines/model",
+  "+ios/chrome/browser/shared/coordinator/scene",
+  "+ios/chrome/browser/url_loading/model",
+]
diff --git a/ios/chrome/app/application_delegate/intents_constants.h b/ios/chrome/browser/intents/intents_constants.h
similarity index 92%
rename from ios/chrome/app/application_delegate/intents_constants.h
rename to ios/chrome/browser/intents/intents_constants.h
index 57a15d3..3cc6e13 100644
--- a/ios/chrome/app/application_delegate/intents_constants.h
+++ b/ios/chrome/browser/intents/intents_constants.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 IOS_CHROME_APP_APPLICATION_DELEGATE_INTENTS_CONSTANTS_H_
-#define IOS_CHROME_APP_APPLICATION_DELEGATE_INTENTS_CONSTANTS_H_
+#ifndef IOS_CHROME_BROWSER_INTENTS_INTENTS_CONSTANTS_H_
+#define IOS_CHROME_BROWSER_INTENTS_INTENTS_CONSTANTS_H_
 
 #import <Foundation/Foundation.h>
 
@@ -65,4 +65,4 @@
 // NSUserActivity for Clear Browsing Data intent.
 extern NSString* const kSiriClearBrowsingData;
 
-#endif  // IOS_CHROME_APP_APPLICATION_DELEGATE_INTENTS_CONSTANTS_H_
+#endif  // IOS_CHROME_BROWSER_INTENTS_INTENTS_CONSTANTS_H_
diff --git a/ios/chrome/app/application_delegate/intents_constants.mm b/ios/chrome/browser/intents/intents_constants.mm
similarity index 96%
rename from ios/chrome/app/application_delegate/intents_constants.mm
rename to ios/chrome/browser/intents/intents_constants.mm
index c48a2637..6e7156ed 100644
--- a/ios/chrome/app/application_delegate/intents_constants.mm
+++ b/ios/chrome/browser/intents/intents_constants.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/app/application_delegate/intents_constants.h"
+#import "ios/chrome/browser/intents/intents_constants.h"
 
 NSString* const kShortcutNewSearch = @"OpenNewSearch";
 NSString* const kShortcutNewIncognitoSearch = @"OpenIncognitoSearch";
diff --git a/ios/chrome/app/application_delegate/user_activity_handler.h b/ios/chrome/browser/intents/user_activity_handler.h
similarity index 92%
rename from ios/chrome/app/application_delegate/user_activity_handler.h
rename to ios/chrome/browser/intents/user_activity_handler.h
index 44bbf11..9d6ef40 100644
--- a/ios/chrome/app/application_delegate/user_activity_handler.h
+++ b/ios/chrome/browser/intents/user_activity_handler.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 IOS_CHROME_APP_APPLICATION_DELEGATE_USER_ACTIVITY_HANDLER_H_
-#define IOS_CHROME_APP_APPLICATION_DELEGATE_USER_ACTIVITY_HANDLER_H_
+#ifndef IOS_CHROME_BROWSER_INTENTS_USER_ACTIVITY_HANDLER_H_
+#define IOS_CHROME_BROWSER_INTENTS_USER_ACTIVITY_HANDLER_H_
 
 #import <UIKit/UIKit.h>
 
@@ -61,4 +61,4 @@
 
 @end
 
-#endif  // IOS_CHROME_APP_APPLICATION_DELEGATE_USER_ACTIVITY_HANDLER_H_
+#endif  // IOS_CHROME_BROWSER_INTENTS_USER_ACTIVITY_HANDLER_H_
diff --git a/ios/chrome/app/application_delegate/user_activity_handler.mm b/ios/chrome/browser/intents/user_activity_handler.mm
similarity index 99%
rename from ios/chrome/app/application_delegate/user_activity_handler.mm
rename to ios/chrome/browser/intents/user_activity_handler.mm
index 3ab6f57..2c1d5e6c 100644
--- a/ios/chrome/app/application_delegate/user_activity_handler.mm
+++ b/ios/chrome/browser/intents/user_activity_handler.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/app/application_delegate/user_activity_handler.h"
+#import "ios/chrome/browser/intents/user_activity_handler.h"
 
 #import <CoreSpotlight/CoreSpotlight.h>
 #import <Intents/Intents.h>
@@ -18,7 +18,7 @@
 #import "components/handoff/handoff_utility.h"
 #import "components/search_engines/template_url_service.h"
 #import "ios/chrome/app/app_startup_parameters.h"
-#import "ios/chrome/app/application_delegate/intents_constants.h"
+#import "ios/chrome/browser/intents/intents_constants.h"
 #import "ios/chrome/app/application_delegate/startup_information.h"
 #import "ios/chrome/app/application_delegate/tab_opening.h"
 #import "ios/chrome/app/application_mode.h"
diff --git a/ios/chrome/app/application_delegate/user_activity_handler_unittest.mm b/ios/chrome/browser/intents/user_activity_handler_unittest.mm
similarity index 99%
rename from ios/chrome/app/application_delegate/user_activity_handler_unittest.mm
rename to ios/chrome/browser/intents/user_activity_handler_unittest.mm
index ec8828f2..a647fd8 100644
--- a/ios/chrome/app/application_delegate/user_activity_handler_unittest.mm
+++ b/ios/chrome/browser/intents/user_activity_handler_unittest.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/app/application_delegate/user_activity_handler.h"
+#import "ios/chrome/browser/intents/user_activity_handler.h"
 
 #import <memory>
 
@@ -21,7 +21,7 @@
 #import "ios/chrome/app/app_startup_parameters.h"
 #import "ios/chrome/app/application_delegate/app_state_observer.h"
 #import "ios/chrome/app/application_delegate/fake_startup_information.h"
-#import "ios/chrome/app/application_delegate/intents_constants.h"
+#import "ios/chrome/browser/intents/intents_constants.h"
 #import "ios/chrome/app/application_delegate/mock_tab_opener.h"
 #import "ios/chrome/app/application_delegate/startup_information.h"
 #import "ios/chrome/app/application_delegate/tab_opening.h"
diff --git a/ios/chrome/browser/main/BUILD.gn b/ios/chrome/browser/main/BUILD.gn
index a6f07ff..a7202f1 100644
--- a/ios/chrome/browser/main/BUILD.gn
+++ b/ios/chrome/browser/main/BUILD.gn
@@ -28,7 +28,6 @@
     "//ios/chrome/browser/lens",
     "//ios/chrome/browser/metrics:metrics_browser_agent",
     "//ios/chrome/browser/metrics/model",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/policy",
     "//ios/chrome/browser/reading_list/model",
     "//ios/chrome/browser/send_tab_to_self/model",
@@ -39,6 +38,7 @@
     "//ios/chrome/browser/shared/model/browser_state",
     "//ios/chrome/browser/shared/model/web_state_list",
     "//ios/chrome/browser/shared/public/commands",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/snapshots/model",
     "//ios/chrome/browser/sync/model:sync_error_browser_agent",
     "//ios/chrome/browser/tab_insertion/model",
diff --git a/ios/chrome/browser/main/DEPS b/ios/chrome/browser/main/DEPS
index 6ef5ed6..f1a290f6 100644
--- a/ios/chrome/browser/main/DEPS
+++ b/ios/chrome/browser/main/DEPS
@@ -16,7 +16,6 @@
     "+ios/chrome/browser/infobars/overlays/browser_agent/infobar_overlay_browser_agent_util.h",
     "+ios/chrome/browser/lens/lens_browser_agent.h",
     "+ios/chrome/browser/metrics/tab_usage_recorder_browser_agent.h",
-    "+ios/chrome/browser/ntp/features.h",
     "+ios/chrome/browser/policy/policy_watcher_browser_agent.h",
     "+ios/chrome/browser/reading_list/model/reading_list_browser_agent.h",
     "+ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent.h",
diff --git a/ios/chrome/browser/main/browser_agent_util.mm b/ios/chrome/browser/main/browser_agent_util.mm
index aa3977a..8e36474 100644
--- a/ios/chrome/browser/main/browser_agent_util.mm
+++ b/ios/chrome/browser/main/browser_agent_util.mm
@@ -15,7 +15,6 @@
 #import "ios/chrome/browser/lens/lens_browser_agent.h"
 #import "ios/chrome/browser/metrics/model/web_state_list_metrics_browser_agent.h"
 #import "ios/chrome/browser/metrics/tab_usage_recorder_browser_agent.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/policy/policy_watcher_browser_agent.h"
 #import "ios/chrome/browser/reading_list/model/reading_list_browser_agent.h"
 #import "ios/chrome/browser/send_tab_to_self/model/send_tab_to_self_browser_agent.h"
@@ -24,6 +23,7 @@
 #import "ios/chrome/browser/sessions/session_service_ios.h"
 #import "ios/chrome/browser/shared/model/application_context/application_context.h"
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/snapshots/model/snapshot_browser_agent.h"
 #import "ios/chrome/browser/sync/model/sync_error_browser_agent.h"
 #import "ios/chrome/browser/tab_insertion/model/tab_insertion_browser_agent.h"
diff --git a/ios/chrome/browser/metrics/BUILD.gn b/ios/chrome/browser/metrics/BUILD.gn
index d6c1846..a78bc1b 100644
--- a/ios/chrome/browser/metrics/BUILD.gn
+++ b/ios/chrome/browser/metrics/BUILD.gn
@@ -121,7 +121,6 @@
     "//ios/chrome/browser/crash_report/model",
     "//ios/chrome/browser/default_browser/model:utils",
     "//ios/chrome/browser/history",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/shared/coordinator/scene:scene_state_header",
     "//ios/chrome/browser/shared/model/application_context",
     "//ios/chrome/browser/shared/model/browser",
@@ -130,6 +129,7 @@
     "//ios/chrome/browser/shared/model/prefs:pref_names",
     "//ios/chrome/browser/shared/model/url:constants",
     "//ios/chrome/browser/shared/model/web_state_list",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/signin",
     "//ios/chrome/browser/sync/model",
     "//ios/chrome/browser/tabs/model",
diff --git a/ios/chrome/browser/metrics/DEPS b/ios/chrome/browser/metrics/DEPS
index bceaecb1..7565b16 100644
--- a/ios/chrome/browser/metrics/DEPS
+++ b/ios/chrome/browser/metrics/DEPS
@@ -3,7 +3,6 @@
   "+ios/chrome/browser/sync/model",
   "+ios/chrome/browser/sessions",
   "+ios/chrome/browser/prerender/model",
-  "+ios/chrome/browser/ntp/features.h",
   "+ios/chrome/browser/variations/model",
   "+ios/chrome/browser/crash_report/model",
   "+ios/chrome/browser/voice/model",
diff --git a/ios/chrome/browser/metrics/ios_feed_enabled_metrics_provider.mm b/ios/chrome/browser/metrics/ios_feed_enabled_metrics_provider.mm
index bf90997de..439dbf2 100644
--- a/ios/chrome/browser/metrics/ios_feed_enabled_metrics_provider.mm
+++ b/ios/chrome/browser/metrics/ios_feed_enabled_metrics_provider.mm
@@ -7,8 +7,8 @@
 #import "base/metrics/histogram_functions.h"
 #import "components/feed/core/shared_prefs/pref_names.h"
 #import "components/prefs/pref_service.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/shared/model/prefs/pref_names.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 
 IOSFeedEnabledMetricsProvider::IOSFeedEnabledMetricsProvider(
     PrefService* pref_service)
diff --git a/ios/chrome/browser/ntp/BUILD.gn b/ios/chrome/browser/ntp/BUILD.gn
index 7907256..4e018cde 100644
--- a/ios/chrome/browser/ntp/BUILD.gn
+++ b/ios/chrome/browser/ntp/BUILD.gn
@@ -45,15 +45,13 @@
 }
 
 source_set("features") {
-  sources = [
-    "features.h",
-    "features.mm",
-  ]
+  sources = [ "features.h" ]
   deps = [
     "//base",
     "//components/country_codes",
     "//components/version_info:channel",
     "//ios/chrome/app:background_mode_buildflags",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/shared/public/features:system_flags",
     "//ios/chrome/common",
   ]
@@ -80,6 +78,7 @@
     "//components/sync/service",
     "//ios/chrome/browser/default_browser/model:utils",
     "//ios/chrome/browser/ntp/home:features",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/signin",
     "//ios/chrome/browser/sync/model",
   ]
@@ -143,6 +142,7 @@
     "//ios/chrome/browser/shared/model/url:constants",
     "//ios/chrome/browser/shared/model/web_state_list",
     "//ios/chrome/browser/shared/model/web_state_list/test:test_support",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/signin",
     "//ios/chrome/browser/signin:fake_system_identity",
     "//ios/chrome/browser/signin:fake_system_identity_manager",
diff --git a/ios/chrome/browser/ntp/features.h b/ios/chrome/browser/ntp/features.h
index 13e70eb..e83631bd3 100644
--- a/ios/chrome/browser/ntp/features.h
+++ b/ios/chrome/browser/ntp/features.h
@@ -5,268 +5,6 @@
 #ifndef IOS_CHROME_BROWSER_NTP_FEATURES_H_
 #define IOS_CHROME_BROWSER_NTP_FEATURES_H_
 
-#import <Foundation/Foundation.h>
-
-#include "base/feature_list.h"
-
-// Engagement criteria type for a feed refresh.
-enum class FeedRefreshEngagementCriteriaType {
-  // Any scroll or interaction.
-  kSimpleEngagement = 0,
-  // Meets minimum scroll criteria or any interaction.
-  kEngagement = 1,
-  // Meets good visit criteria.
-  kGoodVisit = 2,
-  kMaxValue = kGoodVisit,
-};
-
-// Feature flag to enable feed background refresh.
-// Use IsFeedBackgroundRefreshEnabled() instead of this constant directly.
-BASE_DECLARE_FEATURE(kEnableFeedBackgroundRefresh);
-
-// Feature flag to enable feed invisible foreground refresh. Check feature
-// params instead of using this constant.
-BASE_DECLARE_FEATURE(kEnableFeedInvisibleForegroundRefresh);
-
-// Feature flag to enable the Following feed in the NTP.
-// Use IsWebChannelsEnabled() instead of this constant directly.
-BASE_DECLARE_FEATURE(kEnableWebChannels);
-
-// Feature flag to enable Feed card menu promo feature, which displays a sign-in
-// promotion UI when signed out users click on personalization options within
-// the feed card menu.
-// Use IsFeedCardMenuSignInPromoEnabled() instead of this constant directly.
-BASE_DECLARE_FEATURE(kEnableFeedCardMenuSignInPromo);
-
-// Feature flag to disable the feed.
-BASE_DECLARE_FEATURE(kEnableFeedAblation);
-
-// Feature flag to enable feed experiment tagging.
-BASE_DECLARE_FEATURE(kEnableFeedExperimentTagging);
-
-// Feature flag to enable the Set Up List.
-BASE_DECLARE_FEATURE(kIOSSetUpList);
-
-// Feature flag to disable Discover-controlled foregrounding refreshes.
-BASE_DECLARE_FEATURE(kFeedDisableHotStartRefresh);
-
-// Feature flag to enable the Follow UI update.
-BASE_DECLARE_FEATURE(kEnableFollowUIUpdate);
-
-// Feature flag to enable the live sport card in the Discover feed.
-BASE_DECLARE_FEATURE(kDiscoverFeedSportCard);
-
-// Feature flag to enable the content notifications.
-BASE_DECLARE_FEATURE(kContentPushNotifications);
-
-// Feature flag to enable the Large Fakebox design changes.
-BASE_DECLARE_FEATURE(kIOSLargeFakebox);
-
-// Feature flag to enable hiding the feed and feed header depending on Search
-// Engine choice.
-BASE_DECLARE_FEATURE(kIOSHideFeedWithSearchChoice);
-
-// Feature param under `kEnableFeedBackgroundRefresh` to also enable background
-// refresh for the Following feed.
-extern const char kEnableFollowingFeedBackgroundRefresh[];
-
-// Feature param under `kEnableFeedBackgroundRefresh` to enable server driven
-// background refresh schedule.
-extern const char kEnableServerDrivenBackgroundRefreshSchedule[];
-
-// Feature param under `kEnableFeedBackgroundRefresh` to enable recurring
-// background refresh schedule.
-extern const char kEnableRecurringBackgroundRefreshSchedule[];
-
-// Feature param under `kEnableFeedBackgroundRefresh` for the max age that the
-// cache is still considered fresh.
-extern const char kMaxCacheAgeInSeconds[];
-
-// Feature param under `kEnableFeedBackgroundRefresh` for the background refresh
-// interval in seconds.
-extern const char kBackgroundRefreshIntervalInSeconds[];
-
-// Feature param under `kEnableFeedBackgroundRefresh` for the background refresh
-// max age in seconds. This value is compared against the age of the feed when
-// performing a background refresh. A zero value means the age check is ignored.
-extern const char kBackgroundRefreshMaxAgeInSeconds[];
-
-// Feature param under `kEnableFeedInvisibleForegroundRefresh` to enable refresh
-// following a Feed session.
-extern const char kEnableFeedSessionCloseForegroundRefresh[];
-
-// Feature param under `kEnableFeedInvisibleForegroundRefresh` to enable refresh
-// on app backgrounding.
-extern const char kEnableFeedAppCloseForegroundRefresh[];
-
-// Feature param under `kEnableFeedInvisibleForegroundRefresh` to enable refresh
-// soon after the app is backgrounded.
-extern const char kEnableFeedAppCloseBackgroundRefresh[];
-
-// Feature param under `kEnableFeedInvisibleForegroundRefresh` for the
-// engagement criteria type to refresh the feed.
-extern const char kFeedRefreshEngagementCriteriaType[];
-
-// Feature param under `kEnableFeedInvisibleForegroundRefresh` for the
-// background refresh interval in seconds.
-extern const char kAppCloseBackgroundRefreshIntervalInSeconds[];
-
-// Feature param under `kEnableFeedInvisibleForegroundRefresh` for the time
-// interval used to set the refresh timer.
-extern const char kFeedRefreshTimerTimeoutInSeconds[];
-
-// Feature param under `kEnableFeedInvisibleForegroundRefresh` for the refresh
-// threshold when the last refresh was seen.
-extern const char kFeedSeenRefreshThresholdInSeconds[];
-
-// Feature param under `kEnableFeedInvisibleForegroundRefresh` for the refresh
-// threshold when the last refresh was unseen.
-extern const char kFeedUnseenRefreshThresholdInSeconds[];
-
-// Feature param under `kEnableFeedInvisibleForegroundRefresh` to enable using
-// engagement as a signal to invalidate the cache when the app is foregrounded.
-// This can result in a visible refresh when the NTP is visible during
-// foregrounding, or invisible refresh when a non-NTP is shown during
-// foregrounding. The engagement signals may include a deep scroll or 4 views,
-// and no sooner than 5 minutes from the last refresh.
-extern const char
-    kEnableFeedUseInteractivityInvalidationForForegroundRefreshes[];
-
-// Feature param under `kIOSHideFeedWithSearchChoice` to only target the
-// feature at certain countries (i.e. only hide the feed when the device is
-// from those countries when the search engine is changed).
-extern const char kIOSHideFeedWithSearchChoiceTargeted[];
-
-// Whether the Following Feed is enabled on NTP.
-bool IsWebChannelsEnabled();
-
-// Whether the Discover service is created early, alongside the app creation.
-bool IsDiscoverFeedServiceCreatedEarly();
-
-// Whether feed background refresh is enabled and the capability was enabled at
-// startup.
-bool IsFeedBackgroundRefreshEnabled();
-
-// Whether feed background refresh capability is enabled. Returns the value in
-// NSUserDefaults set by
-// `SaveFeedBackgroundRefreshCapabilityEnabledForNextColdStart()`. This is used
-// because registering for background refreshes must happen early in app
-// initialization and FeatureList is not yet available. Enabling or disabling
-// background refresh features will always take effect after two cold starts
-// after the feature has been changed on the server (once for the Finch
-// configuration, and another for reading the stored value from NSUserDefaults).
-// This function always returns false if the `IOS_BACKGROUND_MODE_ENABLED`
-// buildflag is not defined.
-bool IsFeedBackgroundRefreshCapabilityEnabled();
-
-// Saves whether any background refresh experiment is enabled. This call
-// DCHECKs on the availability of `base::FeatureList`.
-void SaveFeedBackgroundRefreshCapabilityEnabledForNextColdStart();
-
-// Sets `timestamp` for key `NSUserDefaultsKey` to be displayed in Experimental
-// Settings in the Settings App. This is not available in stable.
-void SetFeedRefreshTimestamp(NSDate* timestamp, NSString* NSUserDefaultsKey);
-
-// Returns the override value from Experimental Settings in the Settings App. If
-// enabled, all values in Experimental Settings will override all corresponding
-// defaults.
-bool IsFeedOverrideDefaultsEnabled();
-
-// Returns true if the user should receive a local notification when a feed
-// background refresh is completed. Background refresh completion notifications
-// are only enabled by Experimental Settings.
-bool IsFeedBackgroundRefreshCompletedNotificationEnabled();
-
-// Whether the Following feed should also be refreshed in the background.
-bool IsFollowingFeedBackgroundRefreshEnabled();
-
-// Whether the background refresh schedule should be driven by server values.
-bool IsServerDrivenBackgroundRefreshScheduleEnabled();
-
-// Whether a new refresh should be scheduled after completion of a previous
-// background refresh.
-bool IsRecurringBackgroundRefreshScheduleEnabled();
-
-// Returns the max age that the cache is still considered fresh. In other words,
-// the feed freshness threshold.
-double GetFeedMaxCacheAgeInSeconds();
-
-// The earliest interval to refresh if server value is not used. This value is
-// an input into the DiscoverFeedService.
-double GetBackgroundRefreshIntervalInSeconds();
-
-// Returns the background refresh max age in seconds.
-double GetBackgroundRefreshMaxAgeInSeconds();
-
-// Whether feed can be refreshed while not visible.
-bool IsFeedInvisibleForegroundRefreshEnabled();
-
-// Whether feed is refreshed after the user ends a Feed session, but while the
-// app is still in the foreground (e.g., user switches tabs, user navigates away
-// from Feed in current tab).
-bool IsFeedSessionCloseForegroundRefreshEnabled();
-
-// Whether feed is refreshed at the moment the app is backgrounding. This is
-// different from background refresh.
-bool IsFeedAppCloseForegroundRefreshEnabled();
-
-// Whether feed is refreshed in the background soon after the app is
-// backgrounded, and the capability was enabled at startup.
-bool IsFeedAppCloseBackgroundRefreshEnabled();
-
-// Returns the engagement criteria type for a feed refresh.
-FeedRefreshEngagementCriteriaType GetFeedRefreshEngagementCriteriaType();
-
-// The earliest interval to refresh in the background after app enters the
-// background in app close background refresh.
-double GetAppCloseBackgroundRefreshIntervalInSeconds();
-
-// Returns the time interval used to set the session end timer.
-double GetFeedRefreshTimerTimeoutInSeconds();
-
-// Returns the refresh threshold (aka feed expiration) for a feed that has been
-// seen.
-double GetFeedSeenRefreshThresholdInSeconds();
-
-// Returns the refresh threshold (aka feed expiration) for an unseen feed.
-double GetFeedUnseenRefreshThresholdInSeconds();
-
-// Returns whether the feed hide with search choice feature should be targeted
-// only at devices from certain countries.
-bool IsIOSHideFeedWithSearchChoiceTargeted();
-
-// YES if user engagement is used as a signal to invalidate the cache when the
-// app is foregrounded. This can result in a visible refresh when the NTP is
-// visible during foregrounding, or invisible refresh when a non-NTP is shown
-// during foregrounding. The engagement signals may include a deep scroll or 4
-// views, and no sooner than 5 minutes from the last refresh.
-bool IsFeedUseInteractivityInvalidationForForegroundRefreshesEnabled();
-
-// YES if enabled Feed card menu promo.
-bool IsFeedCardMenuSignInPromoEnabled();
-
-// Whether the feed is disabled.
-bool IsFeedAblationEnabled();
-
-// Whether the feed experiment tagging is enabled.
-bool IsFeedExperimentTaggingEnabled();
-
-// Whether the Set Up List feature is enabled.
-bool IsIOSSetUpListEnabled();
-
-// Whether Discover-controlled foregrounding refreshes are disabled.
-bool IsFeedHotStartRefreshDisabled();
-
-// YES when Follow UI Update is enabled.
-bool IsFollowUIUpdateEnabled();
-
-// YES when the Content Push Notifications are enabled.
-bool IsContentPushNotificationsEnabled();
-
-// Returns true when the IOSLargeFakebox feature is enabled.
-bool IsIOSLargeFakeboxEnabled();
-
-// Returns true when the IOSHideFeedWithSearchChoice feature is enabled.
-bool IsIOSHideFeedWithSearchChoiceEnabled();
+#import "ios/chrome/browser/shared/public/features/features.h"
 
 #endif  // IOS_CHROME_BROWSER_NTP_FEATURES_H_
diff --git a/ios/chrome/browser/ntp/features.mm b/ios/chrome/browser/ntp/features.mm
deleted file mode 100644
index 7fd31a3..0000000
--- a/ios/chrome/browser/ntp/features.mm
+++ /dev/null
@@ -1,394 +0,0 @@
-// Copyright 2019 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "ios/chrome/browser/ntp/features.h"
-
-#import <Foundation/Foundation.h>
-
-#import "base/containers/contains.h"
-#import "base/metrics/field_trial_params.h"
-#import "components/country_codes/country_codes.h"
-#import "components/version_info/channel.h"
-#import "ios/chrome/app/background_mode_buildflags.h"
-#import "ios/chrome/browser/shared/public/features/system_flags.h"
-#import "ios/chrome/common/channel_info.h"
-
-namespace {
-
-// Whether feed background refresh is enabled. This only checks if the feature
-// is enabled, not if the capability was enabled at startup.
-bool IsFeedBackgroundRefreshEnabledOnly() {
-  return base::FeatureList::IsEnabled(kEnableFeedBackgroundRefresh);
-}
-
-// Whether feed is refreshed in the background soon after the app is
-// backgrounded. This only checks if the feature is enabled, not if the
-// capability was enabled at startup.
-bool IsFeedAppCloseBackgroundRefreshEnabledOnly() {
-  return base::GetFieldTrialParamByFeatureAsBool(
-      kEnableFeedInvisibleForegroundRefresh,
-      kEnableFeedAppCloseBackgroundRefresh,
-      /*default=*/false);
-}
-
-// Returns the override value from the Foreground Refresh section of Feed
-// Refresh Settings in Experimental Settings in the Settings App.
-bool IsFeedOverrideForegroundDefaultsEnabled() {
-  if (GetChannel() == version_info::Channel::STABLE) {
-    return false;
-  }
-  return [[NSUserDefaults standardUserDefaults]
-      boolForKey:@"FeedOverrideForegroundDefaultsEnabled"];
-}
-
-}  // namespace
-
-BASE_FEATURE(kEnableWebChannels,
-             "EnableWebChannels",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-BASE_FEATURE(kEnableFeedBackgroundRefresh,
-             "EnableFeedBackgroundRefresh",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-BASE_FEATURE(kEnableFeedInvisibleForegroundRefresh,
-             "EnableFeedInvisibleForegroundRefresh",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
-BASE_FEATURE(kCreateDiscoverFeedServiceEarly,
-             "CreateDiscoverFeedServiceEarly",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-BASE_FEATURE(kEnableFeedCardMenuSignInPromo,
-             "EnableFeedCardMenuSignInPromo",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
-BASE_FEATURE(kEnableFeedAblation,
-             "EnableFeedAblation",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-BASE_FEATURE(kEnableFeedExperimentTagging,
-             "EnableFeedExperimentTagging",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
-BASE_FEATURE(kIOSSetUpList, "IOSSetUpList", base::FEATURE_ENABLED_BY_DEFAULT);
-
-BASE_FEATURE(kFeedDisableHotStartRefresh,
-             "FeedDisableHotStartRefresh",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-BASE_FEATURE(kEnableFollowUIUpdate,
-             "EnableFollowUIUpdate",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-BASE_FEATURE(kDiscoverFeedSportCard,
-             "DiscoverFeedSportCard",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-BASE_FEATURE(kContentPushNotifications,
-             "ContentPushNotifications",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-BASE_FEATURE(kIOSLargeFakebox,
-             "IOSLargeFakebox",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-BASE_FEATURE(kIOSHideFeedWithSearchChoice,
-             "IOSHideFeedWithSearchChoice",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-// Key for NSUserDefaults containing a bool indicating whether the next run
-// should enable feed background refresh capability. This is used because
-// registering for background refreshes must happen early in app initialization
-// and FeatureList is not yet available. Enabling or disabling background
-// refresh features will always take effect after two cold starts after the
-// feature has been changed on the server (once for the Finch configuration, and
-// another for reading the stored value from NSUserDefaults).
-NSString* const kEnableFeedBackgroundRefreshCapabilityForNextColdStart =
-    @"EnableFeedBackgroundRefreshCapabilityForNextColdStart";
-
-const char kEnableFollowingFeedBackgroundRefresh[] =
-    "EnableFollowingFeedBackgroundRefresh";
-const char kEnableServerDrivenBackgroundRefreshSchedule[] =
-    "EnableServerDrivenBackgroundRefreshSchedule";
-const char kEnableRecurringBackgroundRefreshSchedule[] =
-    "EnableRecurringBackgroundRefreshSchedule";
-const char kMaxCacheAgeInSeconds[] = "MaxCacheAgeInSeconds";
-const char kBackgroundRefreshIntervalInSeconds[] =
-    "BackgroundRefreshIntervalInSeconds";
-const char kBackgroundRefreshMaxAgeInSeconds[] =
-    "BackgroundRefreshMaxAgeInSeconds";
-const char kEnableFeedSessionCloseForegroundRefresh[] =
-    "EnableFeedSessionCloseForegroundRefresh";
-const char kEnableFeedAppCloseForegroundRefresh[] =
-    "EnableFeedAppCloseForegroundRefresh";
-const char kEnableFeedAppCloseBackgroundRefresh[] =
-    "EnableFeedAppCloseBackgroundRefresh";
-const char kFeedRefreshEngagementCriteriaType[] =
-    "FeedRefreshEngagementCriteriaType";
-const char kAppCloseBackgroundRefreshIntervalInSeconds[] =
-    "AppCloseBackgroundRefreshIntervalInSeconds";
-const char kFeedRefreshTimerTimeoutInSeconds[] =
-    "FeedRefreshTimerTimeoutInSeconds";
-const char kFeedSeenRefreshThresholdInSeconds[] =
-    "FeedSeenRefreshThresholdInSeconds";
-const char kFeedUnseenRefreshThresholdInSeconds[] =
-    "FeedUnseenRefreshThresholdInSeconds";
-const char kEnableFeedUseInteractivityInvalidationForForegroundRefreshes[] =
-    "EnableFeedUseInteractivityInvalidationForForegroundRefreshes";
-const char kIOSHideFeedWithSearchChoiceTargeted[] =
-    "IOSHideFeedWithSearchChoiceTargeted";
-
-bool IsWebChannelsEnabled() {
-  std::string launched_countries[6] = {"AU", "CA", "GB", "NZ", "US", "ZA"};
-  if (base::Contains(launched_countries,
-                     country_codes::GetCurrentCountryCode())) {
-    return true;
-  }
-  return base::FeatureList::IsEnabled(kEnableWebChannels);
-}
-
-bool IsDiscoverFeedServiceCreatedEarly() {
-  return base::FeatureList::IsEnabled(kCreateDiscoverFeedServiceEarly);
-}
-
-bool IsFeedBackgroundRefreshEnabled() {
-  return IsFeedBackgroundRefreshCapabilityEnabled() &&
-         IsFeedBackgroundRefreshEnabledOnly();
-}
-
-bool IsFeedBackgroundRefreshCapabilityEnabled() {
-#if !BUILDFLAG(IOS_BACKGROUND_MODE_ENABLED)
-  return false;
-#else
-  static bool feedBackgroundRefreshEnabled =
-      [[NSUserDefaults standardUserDefaults]
-          boolForKey:kEnableFeedBackgroundRefreshCapabilityForNextColdStart];
-  return feedBackgroundRefreshEnabled;
-#endif  // BUILDFLAG(IOS_BACKGROUND_MODE_ENABLED)
-}
-
-void SaveFeedBackgroundRefreshCapabilityEnabledForNextColdStart() {
-  DCHECK(base::FeatureList::GetInstance());
-  BOOL enabled = IsFeedBackgroundRefreshEnabledOnly() ||
-                 IsFeedAppCloseBackgroundRefreshEnabledOnly();
-  [[NSUserDefaults standardUserDefaults]
-      setBool:enabled
-       forKey:kEnableFeedBackgroundRefreshCapabilityForNextColdStart];
-}
-
-void SetFeedRefreshTimestamp(NSDate* timestamp, NSString* NSUserDefaultsKey) {
-  NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
-  dateFormatter.dateStyle = NSDateFormatterShortStyle;
-  dateFormatter.timeStyle = NSDateFormatterShortStyle;
-  dateFormatter.locale = [NSLocale autoupdatingCurrentLocale];
-  [[NSUserDefaults standardUserDefaults]
-      setObject:[dateFormatter stringFromDate:timestamp]
-         forKey:NSUserDefaultsKey];
-}
-
-bool IsFeedOverrideDefaultsEnabled() {
-  if (GetChannel() == version_info::Channel::STABLE) {
-    return false;
-  }
-  return [[NSUserDefaults standardUserDefaults]
-      boolForKey:@"FeedOverrideDefaultsEnabled"];
-}
-
-bool IsFeedBackgroundRefreshCompletedNotificationEnabled() {
-  if (GetChannel() == version_info::Channel::STABLE) {
-    return false;
-  }
-  return IsFeedBackgroundRefreshCapabilityEnabled() &&
-         [[NSUserDefaults standardUserDefaults]
-             boolForKey:@"FeedBackgroundRefreshNotificationEnabled"];
-}
-
-bool IsFollowingFeedBackgroundRefreshEnabled() {
-  if (IsFeedOverrideDefaultsEnabled()) {
-    return [[NSUserDefaults standardUserDefaults]
-        boolForKey:@"FollowingFeedBackgroundRefreshEnabled"];
-  }
-  return base::GetFieldTrialParamByFeatureAsBool(
-      kEnableFeedBackgroundRefresh, kEnableFollowingFeedBackgroundRefresh,
-      /*default=*/false);
-}
-
-bool IsServerDrivenBackgroundRefreshScheduleEnabled() {
-  if (IsFeedOverrideDefaultsEnabled()) {
-    return [[NSUserDefaults standardUserDefaults]
-        boolForKey:@"FeedServerDrivenBackgroundRefreshScheduleEnabled"];
-  }
-  return base::GetFieldTrialParamByFeatureAsBool(
-      kEnableFeedBackgroundRefresh,
-      kEnableServerDrivenBackgroundRefreshSchedule, /*default=*/false);
-}
-
-bool IsRecurringBackgroundRefreshScheduleEnabled() {
-  if (IsFeedOverrideDefaultsEnabled()) {
-    return [[NSUserDefaults standardUserDefaults]
-        boolForKey:@"FeedRecurringBackgroundRefreshScheduleEnabled"];
-  }
-  return base::GetFieldTrialParamByFeatureAsBool(
-      kEnableFeedBackgroundRefresh, kEnableRecurringBackgroundRefreshSchedule,
-      /*default=*/false);
-}
-
-double GetFeedMaxCacheAgeInSeconds() {
-  if (IsFeedOverrideDefaultsEnabled()) {
-    return [[NSUserDefaults standardUserDefaults]
-        doubleForKey:@"FeedMaxCacheAgeInSeconds"];
-  }
-  return base::GetFieldTrialParamByFeatureAsDouble(kEnableFeedBackgroundRefresh,
-                                                   kMaxCacheAgeInSeconds,
-                                                   /*default=*/8 * 60 * 60);
-}
-
-double GetBackgroundRefreshIntervalInSeconds() {
-  if (IsFeedOverrideDefaultsEnabled()) {
-    return [[NSUserDefaults standardUserDefaults]
-        doubleForKey:@"FeedBackgroundRefreshIntervalInSeconds"];
-  }
-  return base::GetFieldTrialParamByFeatureAsDouble(
-      kEnableFeedBackgroundRefresh, kBackgroundRefreshIntervalInSeconds,
-      /*default=*/60 * 60);
-}
-
-double GetBackgroundRefreshMaxAgeInSeconds() {
-  return base::GetFieldTrialParamByFeatureAsDouble(
-      kEnableFeedBackgroundRefresh, kBackgroundRefreshMaxAgeInSeconds,
-      /*default=*/0);
-}
-
-bool IsFeedInvisibleForegroundRefreshEnabled() {
-  return base::FeatureList::IsEnabled(kEnableFeedInvisibleForegroundRefresh);
-}
-
-bool IsFeedSessionCloseForegroundRefreshEnabled() {
-  return base::GetFieldTrialParamByFeatureAsBool(
-      kEnableFeedInvisibleForegroundRefresh,
-      kEnableFeedSessionCloseForegroundRefresh,
-      /*default=*/false);
-}
-
-bool IsFeedAppCloseForegroundRefreshEnabled() {
-  return base::GetFieldTrialParamByFeatureAsBool(
-      kEnableFeedInvisibleForegroundRefresh,
-      kEnableFeedAppCloseForegroundRefresh,
-      /*default=*/true);
-}
-
-bool IsFeedAppCloseBackgroundRefreshEnabled() {
-  return IsFeedBackgroundRefreshCapabilityEnabled() &&
-         IsFeedAppCloseBackgroundRefreshEnabledOnly();
-}
-
-FeedRefreshEngagementCriteriaType GetFeedRefreshEngagementCriteriaType() {
-  return (FeedRefreshEngagementCriteriaType)
-      base::GetFieldTrialParamByFeatureAsInt(
-          kEnableFeedInvisibleForegroundRefresh,
-          kFeedRefreshEngagementCriteriaType,
-          /*default_value=*/
-          (int)FeedRefreshEngagementCriteriaType::kSimpleEngagement);
-}
-
-double GetAppCloseBackgroundRefreshIntervalInSeconds() {
-  double override_value = [[NSUserDefaults standardUserDefaults]
-      doubleForKey:@"AppCloseBackgroundRefreshIntervalInSeconds"];
-  if (override_value > 0.0) {
-    return override_value;
-  }
-  return base::GetFieldTrialParamByFeatureAsDouble(
-      kEnableFeedInvisibleForegroundRefresh,
-      kAppCloseBackgroundRefreshIntervalInSeconds,
-      /*default=*/base::Minutes(5).InSecondsF());
-}
-
-double GetFeedRefreshTimerTimeoutInSeconds() {
-  double override_value = [[NSUserDefaults standardUserDefaults]
-      doubleForKey:@"FeedRefreshTimerTimeoutInSeconds"];
-  if (override_value > 0.0) {
-    return override_value;
-  }
-  return base::GetFieldTrialParamByFeatureAsDouble(
-      kEnableFeedInvisibleForegroundRefresh, kFeedRefreshTimerTimeoutInSeconds,
-      /*default=*/base::Minutes(5).InSecondsF());
-}
-
-double GetFeedSeenRefreshThresholdInSeconds() {
-  double override_value = [[NSUserDefaults standardUserDefaults]
-      doubleForKey:@"FeedSeenRefreshThresholdInSeconds"];
-  if (override_value > 0.0) {
-    return override_value;
-  }
-  return base::GetFieldTrialParamByFeatureAsDouble(
-      kEnableFeedInvisibleForegroundRefresh, kFeedSeenRefreshThresholdInSeconds,
-      /*default=*/base::Hours(1).InSecondsF());
-}
-
-double GetFeedUnseenRefreshThresholdInSeconds() {
-  double override_value = [[NSUserDefaults standardUserDefaults]
-      doubleForKey:@"FeedUnseenRefreshThresholdInSeconds"];
-  if (override_value > 0.0) {
-    return override_value;
-  }
-  return base::GetFieldTrialParamByFeatureAsDouble(
-      kEnableFeedInvisibleForegroundRefresh,
-      kFeedUnseenRefreshThresholdInSeconds,
-      /*default=*/base::Hours(6).InSecondsF());
-}
-
-bool IsFeedUseInteractivityInvalidationForForegroundRefreshesEnabled() {
-  if (IsFeedOverrideForegroundDefaultsEnabled()) {
-    return [[NSUserDefaults standardUserDefaults]
-        doubleForKey:
-            @"FeedUseInteractivityInvalidationForForegroundRefreshesEnabled"];
-  }
-  return base::GetFieldTrialParamByFeatureAsBool(
-      kEnableFeedInvisibleForegroundRefresh,
-      kEnableFeedUseInteractivityInvalidationForForegroundRefreshes,
-      /*default=*/false);
-}
-
-bool IsIOSHideFeedWithSearchChoiceTargeted() {
-  return base::GetFieldTrialParamByFeatureAsBool(
-      kIOSHideFeedWithSearchChoice, kIOSHideFeedWithSearchChoiceTargeted,
-      /*default=*/false);
-}
-
-bool IsFeedCardMenuSignInPromoEnabled() {
-  return base::FeatureList::IsEnabled(kEnableFeedCardMenuSignInPromo);
-}
-
-bool IsFeedAblationEnabled() {
-  return base::FeatureList::IsEnabled(kEnableFeedAblation);
-}
-
-bool IsFeedExperimentTaggingEnabled() {
-  return base::FeatureList::IsEnabled(kEnableFeedExperimentTagging);
-}
-
-bool IsIOSSetUpListEnabled() {
-  return base::FeatureList::IsEnabled(kIOSSetUpList);
-}
-
-bool IsFeedHotStartRefreshDisabled() {
-  return base::FeatureList::IsEnabled(kFeedDisableHotStartRefresh);
-}
-
-bool IsFollowUIUpdateEnabled() {
-  return base::FeatureList::IsEnabled(kEnableFollowUIUpdate);
-}
-
-bool IsContentPushNotificationsEnabled() {
-  return base::FeatureList::IsEnabled(kContentPushNotifications);
-}
-
-bool IsIOSLargeFakeboxEnabled() {
-  return base::FeatureList::IsEnabled(kIOSLargeFakebox);
-}
-
-bool IsIOSHideFeedWithSearchChoiceEnabled() {
-  return base::FeatureList::IsEnabled(kIOSHideFeedWithSearchChoice);
-}
diff --git a/ios/chrome/browser/ntp/home/BUILD.gn b/ios/chrome/browser/ntp/home/BUILD.gn
index 72de097c..e497d00 100644
--- a/ios/chrome/browser/ntp/home/BUILD.gn
+++ b/ios/chrome/browser/ntp/home/BUILD.gn
@@ -3,10 +3,7 @@
 # found in the LICENSE file.
 
 source_set("features") {
-  sources = [
-    "features.h",
-    "features.mm",
-  ]
+  sources = [ "features.h" ]
   public_deps = [ "//base" ]
   deps = [
     "//components/prefs",
diff --git a/ios/chrome/browser/ntp/home/features.h b/ios/chrome/browser/ntp/home/features.h
index c2238c5..a85e627d 100644
--- a/ios/chrome/browser/ntp/home/features.h
+++ b/ios/chrome/browser/ntp/home/features.h
@@ -5,94 +5,4 @@
 #ifndef IOS_CHROME_BROWSER_NTP_HOME_FEATURES_H_
 #define IOS_CHROME_BROWSER_NTP_HOME_FEATURES_H_
 
-#import "base/feature_list.h"
-
-namespace base {
-class TimeDelta;
-}  // namespace base
-
-// Feature to choose between the old Zine feed or the new Discover feed in the
-// Bling new tab page.
-// Use IsDiscoverFeedEnabled() instead of this constant directly.
-// TODO(crbug.com/1385512): Remove this.
-BASE_DECLARE_FEATURE(kDiscoverFeedInNtp);
-
-// Feature to use one NTP for all tabs in a Browser.
-BASE_DECLARE_FEATURE(kSingleNtp);
-
-// Feature for the Magic Stack.
-BASE_DECLARE_FEATURE(kMagicStack);
-
-// Feature that contains the feed in a module.
-BASE_DECLARE_FEATURE(kEnableFeedContainment);
-
-// Feature that enables tab resumption.
-BASE_DECLARE_FEATURE(kTabResumption);
-
-// A parameter to indicate whether the Most Visited Tiles should be in the Magic
-// Stack.
-extern const char kMagicStackMostVisitedModuleParam[];
-
-// A parameter representing how much to reduce the NTP top space margin. If it
-// is negative, it will increase the top space margin.
-extern const char kReducedSpaceParam[];
-
-// A parameter representing whether modules should not be added to the Magic
-// Stack if their content is irrelevant.
-extern const char kHideIrrelevantModulesParam[];
-
-// A parameter representing how many days before showing the compacted Set Up
-// List module in the Magic Stack.
-extern const char kSetUpListCompactedTimeThresholdDays[];
-
-// A parameter to indicate whether the native UI is enabled for the discover
-// feed.
-// TODO(crbug.com/1385512): Remove this.
-extern const char kDiscoverFeedIsNativeUIEnabled[];
-
-// Feature parameters for the tab resumption feature. If no parameter is set,
-// the default (most recent tab only) will be used.
-extern const char kTabResumptionParameterName[];
-extern const char kTabResumptionMostRecentTabOnlyParam[];
-extern const char kTabResumptionAllTabsParam[];
-extern const char kTabResumptionAllTabsOneDayThresholdParam[];
-
-// Whether the Discover feed is enabled instead of the Zine feed.
-// TODO(crbug.com/1385512): Remove this.
-bool IsDiscoverFeedEnabled();
-
-// Whether the Magic Stack should be shown.
-bool IsMagicStackEnabled();
-
-// Whether the feed is contained in a Home module.
-bool IsFeedContainmentEnabled();
-
-// The minimum padding between the modules and the screen bounds on the Home
-// surface. Relies on `IsFeedContainmentEnabled()` being enabled.
-int HomeModuleMinimumPadding();
-
-// Whether the tab resumption feature is enabled.
-bool IsTabResumptionEnabled();
-
-// Whether the tab resumption feature is enabled for most recent tab only.
-bool IsTabResumptionEnabledForMostRecentTabOnly();
-
-// Convenience method for determining the tab resumption time threshold for
-// X-Devices tabs only.
-const base::TimeDelta TabResumptionForXDevicesTimeThreshold();
-
-// Whether the Most Visited Sites should be put into the Magic Stack.
-bool ShouldPutMostVisitedSitesInMagicStack();
-
-// How much the NTP top margin should be reduced by for the Magic Stack design.
-double ReducedNTPTopMarginSpaceForMagicStack();
-
-// Whether modules should not be added to the Magic Stack if their content is
-// irrelevant.
-bool ShouldHideIrrelevantModules();
-
-// How many days before showing the Compacted Set Up List module configuration
-// in the Magic Stack.
-int TimeUntilShowingCompactedSetUpList();
-
 #endif  // IOS_CHROME_BROWSER_NTP_HOME_FEATURES_H_
diff --git a/ios/chrome/browser/ntp/home/features.mm b/ios/chrome/browser/ntp/home/features.mm
deleted file mode 100644
index a946ab3..0000000
--- a/ios/chrome/browser/ntp/home/features.mm
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "ios/chrome/browser/ntp/home/features.h"
-
-#import "base/metrics/field_trial.h"
-#import "base/metrics/field_trial_params.h"
-#import "base/time/time.h"
-#import "components/prefs/pref_service.h"
-#import "ios/chrome/browser/shared/model/application_context/application_context.h"
-
-// Feature disabled by default to keep showing old Zine feed.
-BASE_FEATURE(kDiscoverFeedInNtp,
-             "DiscoverFeedInNtp",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
-// Feature disabled by default.
-BASE_FEATURE(kSingleNtp, "SingleNTP", base::FEATURE_ENABLED_BY_DEFAULT);
-
-// Feature disabled by default.
-BASE_FEATURE(kMagicStack, "MagicStack", base::FEATURE_DISABLED_BY_DEFAULT);
-
-BASE_FEATURE(kEnableFeedContainment,
-             "EnableFeedContainment",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-BASE_FEATURE(kTabResumption,
-             "TabResumption",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-const char kMagicStackMostVisitedModuleParam[] = "MagicStackMostVisitedModule";
-
-const char kReducedSpaceParam[] = "ReducedNTPTopSpace";
-
-const char kHideIrrelevantModulesParam[] = "HideIrrelevantModules";
-
-const char kSetUpListCompactedTimeThresholdDays[] =
-    "SetUpListCompactedTimeThresholdDays";
-
-const char kHomeModuleMinimumPadding[] = "HomeModuleMinimumPadding";
-
-// A parameter to indicate whether the native UI is enabled for the discover
-// feed.
-const char kDiscoverFeedIsNativeUIEnabled[] = "DiscoverFeedIsNativeUIEnabled";
-
-const char kTabResumptionParameterName[] = "variant";
-const char kTabResumptionMostRecentTabOnlyParam[] =
-    "tab-resumption-recent-tab-only";
-const char kTabResumptionAllTabsParam[] = "tab-resumption-all-tabs";
-const char kTabResumptionAllTabsOneDayThresholdParam[] =
-    "tab-resumption-all-tabs-one-day-threshold";
-
-bool IsDiscoverFeedEnabled() {
-  return base::FeatureList::IsEnabled(kDiscoverFeedInNtp);
-}
-
-bool IsMagicStackEnabled() {
-  return base::FeatureList::IsEnabled(kMagicStack);
-}
-
-bool IsFeedContainmentEnabled() {
-  return base::FeatureList::IsEnabled(kEnableFeedContainment);
-}
-
-int HomeModuleMinimumPadding() {
-  return base::GetFieldTrialParamByFeatureAsInt(kEnableFeedContainment,
-                                                kHomeModuleMinimumPadding, 30);
-}
-
-bool IsTabResumptionEnabled() {
-  return IsMagicStackEnabled() && base::FeatureList::IsEnabled(kTabResumption);
-}
-
-bool IsTabResumptionEnabledForMostRecentTabOnly() {
-  CHECK(IsTabResumptionEnabled());
-  std::string feature_param = base::GetFieldTrialParamValueByFeature(
-      kTabResumption, kTabResumptionParameterName);
-  return feature_param == kTabResumptionMostRecentTabOnlyParam;
-}
-
-const base::TimeDelta TabResumptionForXDevicesTimeThreshold() {
-  CHECK(!IsTabResumptionEnabledForMostRecentTabOnly());
-
-  std::string feature_param = base::GetFieldTrialParamValueByFeature(
-      kTabResumption, kTabResumptionParameterName);
-  if (feature_param == kTabResumptionAllTabsOneDayThresholdParam) {
-    return base::Days(1);
-  }
-  return base::Hours(12);
-}
-
-bool ShouldPutMostVisitedSitesInMagicStack() {
-  return base::GetFieldTrialParamByFeatureAsBool(
-      kMagicStack, kMagicStackMostVisitedModuleParam, false);
-}
-
-double ReducedNTPTopMarginSpaceForMagicStack() {
-  return base::GetFieldTrialParamByFeatureAsDouble(kMagicStack,
-                                                   kReducedSpaceParam, 0);
-}
-
-bool ShouldHideIrrelevantModules() {
-  return base::GetFieldTrialParamByFeatureAsBool(
-      kMagicStack, kHideIrrelevantModulesParam, false);
-}
-
-int TimeUntilShowingCompactedSetUpList() {
-  return base::GetFieldTrialParamByFeatureAsInt(
-      kMagicStack, kSetUpListCompactedTimeThresholdDays, 3);
-}
diff --git a/ios/chrome/browser/ntp/new_tab_page_tab_helper.mm b/ios/chrome/browser/ntp/new_tab_page_tab_helper.mm
index 865f3c2..4e8f345 100644
--- a/ios/chrome/browser/ntp/new_tab_page_tab_helper.mm
+++ b/ios/chrome/browser/ntp/new_tab_page_tab_helper.mm
@@ -11,11 +11,11 @@
 #import "base/strings/string_util.h"
 #import "base/strings/sys_string_conversions.h"
 #import "components/strings/grit/components_strings.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/ntp/new_tab_page_state.h"
 #import "ios/chrome/browser/ntp/new_tab_page_tab_helper_delegate.h"
 #import "ios/chrome/browser/shared/model/url/chrome_url_constants.h"
 #import "ios/chrome/browser/shared/model/url/url_util.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/web/common/features.h"
 #import "ios/web/public/navigation/navigation_context.h"
 #import "ios/web/public/navigation/navigation_item.h"
diff --git a/ios/chrome/browser/ntp/set_up_list.mm b/ios/chrome/browser/ntp/set_up_list.mm
index 3a5395b..4c4adcd8 100644
--- a/ios/chrome/browser/ntp/set_up_list.mm
+++ b/ios/chrome/browser/ntp/set_up_list.mm
@@ -11,12 +11,12 @@
 #import "components/sync/service/sync_service.h"
 #import "components/sync/service/sync_user_settings.h"
 #import "ios/chrome/browser/default_browser/model/utils.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/ntp/set_up_list_delegate.h"
 #import "ios/chrome/browser/ntp/set_up_list_item.h"
 #import "ios/chrome/browser/ntp/set_up_list_item_type.h"
 #import "ios/chrome/browser/ntp/set_up_list_metrics.h"
 #import "ios/chrome/browser/ntp/set_up_list_prefs.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/signin/authentication_service.h"
 #import "ios/chrome/browser/sync/model/enterprise_utils.h"
 
diff --git a/ios/chrome/browser/ntp/set_up_list_unittest.mm b/ios/chrome/browser/ntp/set_up_list_unittest.mm
index 243b7df3..4880958 100644
--- a/ios/chrome/browser/ntp/set_up_list_unittest.mm
+++ b/ios/chrome/browser/ntp/set_up_list_unittest.mm
@@ -12,7 +12,6 @@
 #import "components/sync_preferences/testing_pref_service_syncable.h"
 #import "ios/chrome/browser/default_browser/model/utils.h"
 #import "ios/chrome/browser/default_browser/model/utils_test_support.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/ntp/set_up_list_delegate.h"
 #import "ios/chrome/browser/ntp/set_up_list_item.h"
 #import "ios/chrome/browser/ntp/set_up_list_item_type.h"
@@ -21,6 +20,7 @@
 #import "ios/chrome/browser/shared/model/application_context/application_context.h"
 #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h"
 #import "ios/chrome/browser/shared/model/prefs/pref_names.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/signin/authentication_service.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/signin/fake_authentication_service_delegate.h"
diff --git a/ios/chrome/browser/ntp_tiles/model/BUILD.gn b/ios/chrome/browser/ntp_tiles/model/BUILD.gn
index a52c27a..5a06c49 100644
--- a/ios/chrome/browser/ntp_tiles/model/BUILD.gn
+++ b/ios/chrome/browser/ntp_tiles/model/BUILD.gn
@@ -37,6 +37,7 @@
   deps = [
     "//base/test:test_support",
     "//ios/chrome/browser/ntp/home:features",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/test/earl_grey:eg_test_support+eg2",
     "//ios/testing/earl_grey:eg_test_support+eg2",
     "//ios/web/public/test/http_server:http_server",
diff --git a/ios/chrome/browser/ntp_tiles/model/ntp_tiles_egtest.mm b/ios/chrome/browser/ntp_tiles/model/ntp_tiles_egtest.mm
index 3a632c3..be11cf5 100644
--- a/ios/chrome/browser/ntp_tiles/model/ntp_tiles_egtest.mm
+++ b/ios/chrome/browser/ntp_tiles/model/ntp_tiles_egtest.mm
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 #import "base/test/ios/wait_util.h"
-#import "ios/chrome/browser/ntp/home/features.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
 #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
 #import "ios/chrome/test/earl_grey/chrome_matchers.h"
diff --git a/ios/chrome/browser/photos/BUILD.gn b/ios/chrome/browser/photos/BUILD.gn
deleted file mode 100644
index 86857dce..0000000
--- a/ios/chrome/browser/photos/BUILD.gn
+++ /dev/null
@@ -1,22 +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.
-
-# TODO(crbug.com/1498935): Remove these source sets once they are not referred anymore.
-
-source_set("photos") {
-  sources = [
-    "photos_service.h",
-    "photos_service_configuration.h",
-  ]
-  public_deps = [
-    "//base",
-    "//components/keyed_service/core",
-    "//ios/chrome/browser/photos/model",
-  ]
-}
-
-source_set("metrics") {
-  sources = [ "photos_metrics.h" ]
-  public_deps = [ "//ios/chrome/browser/photos/model:metrics" ]
-}
diff --git a/ios/chrome/browser/photos/photos_metrics.h b/ios/chrome/browser/photos/photos_metrics.h
deleted file mode 100644
index 0a78f07..0000000
--- a/ios/chrome/browser/photos/photos_metrics.h
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_PHOTOS_PHOTOS_METRICS_H_
-#define IOS_CHROME_BROWSER_PHOTOS_PHOTOS_METRICS_H_
-
-// TODO(crbug.com/1498935): Remove this file once it is not imported anymore.
-#import "ios/chrome/browser/photos/model/photos_metrics.h"
-
-#endif  // IOS_CHROME_BROWSER_PHOTOS_PHOTOS_METRICS_H_
diff --git a/ios/chrome/browser/photos/photos_service.h b/ios/chrome/browser/photos/photos_service.h
deleted file mode 100644
index 4e7ca4d..0000000
--- a/ios/chrome/browser/photos/photos_service.h
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_PHOTOS_PHOTOS_SERVICE_H_
-#define IOS_CHROME_BROWSER_PHOTOS_PHOTOS_SERVICE_H_
-
-// TODO(crbug.com/1498935): Remove this file once it is not imported anymore.
-#import "ios/chrome/browser/photos/model/photos_service.h"
-
-#endif  // IOS_CHROME_BROWSER_PHOTOS_PHOTOS_SERVICE_H_
diff --git a/ios/chrome/browser/photos/photos_service_configuration.h b/ios/chrome/browser/photos/photos_service_configuration.h
deleted file mode 100644
index 5805c3e..0000000
--- a/ios/chrome/browser/photos/photos_service_configuration.h
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_PHOTOS_PHOTOS_SERVICE_CONFIGURATION_H_
-#define IOS_CHROME_BROWSER_PHOTOS_PHOTOS_SERVICE_CONFIGURATION_H_
-
-// TODO(crbug.com/1498935): Remove this file once it is not imported anymore.
-#import "ios/chrome/browser/photos/model/photos_service_configuration.h"
-
-#endif  // IOS_CHROME_BROWSER_PHOTOS_PHOTOS_SERVICE_CONFIGURATION_H_
diff --git a/ios/chrome/browser/policy/BUILD.gn b/ios/chrome/browser/policy/BUILD.gn
index d8eee806..bcd5382 100644
--- a/ios/chrome/browser/policy/BUILD.gn
+++ b/ios/chrome/browser/policy/BUILD.gn
@@ -274,11 +274,11 @@
     "//components/sync/base:features",
     "//google_apis",
     "//ios/chrome/app/strings",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/ntp/home:features",
     "//ios/chrome/browser/policy:eg_test_support+eg2",
     "//ios/chrome/browser/shared/model/prefs:pref_names",
     "//ios/chrome/browser/shared/model/url:constants",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/signin:fake_system_identity",
     "//ios/chrome/browser/translate/model:eg_test_support+eg2",
     "//ios/chrome/browser/ui/authentication:eg_test_support+eg2",
diff --git a/ios/chrome/browser/policy/policy_egtest.mm b/ios/chrome/browser/policy/policy_egtest.mm
index cef7a6e..547c2348 100644
--- a/ios/chrome/browser/policy/policy_egtest.mm
+++ b/ios/chrome/browser/policy/policy_egtest.mm
@@ -21,13 +21,12 @@
 #import "components/safe_browsing/core/common/features.h"
 #import "components/strings/grit/components_strings.h"
 #import "components/sync/base/features.h"
-#import "ios/chrome/browser/ntp/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/policy/cloud/user_policy_constants.h"
 #import "ios/chrome/browser/policy/policy_app_interface.h"
 #import "ios/chrome/browser/policy/policy_earl_grey_utils.h"
 #import "ios/chrome/browser/shared/model/prefs/pref_names.h"
 #import "ios/chrome/browser/shared/model/url/chrome_url_constants.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/signin/fake_system_identity.h"
 #import "ios/chrome/browser/translate/model/translate_app_interface.h"
 #import "ios/chrome/browser/ui/authentication/signin_earl_grey.h"
diff --git a/ios/chrome/browser/push_notification/model/BUILD.gn b/ios/chrome/browser/push_notification/model/BUILD.gn
new file mode 100644
index 0000000..d5c7b67
--- /dev/null
+++ b/ios/chrome/browser/push_notification/model/BUILD.gn
@@ -0,0 +1,9 @@
+# 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.
+
+source_set("model") {
+  sources = [ "push_notification_service.h" ]
+  public_deps =
+      [ "//ios/chrome/browser/push_notification:push_notification_service" ]
+}
diff --git a/ios/chrome/browser/push_notification/model/push_notification_service.h b/ios/chrome/browser/push_notification/model/push_notification_service.h
new file mode 100644
index 0000000..4d26c46
--- /dev/null
+++ b/ios/chrome/browser/push_notification/model/push_notification_service.h
@@ -0,0 +1,10 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_PUSH_NOTIFICATION_MODEL_PUSH_NOTIFICATION_SERVICE_H_
+#define IOS_CHROME_BROWSER_PUSH_NOTIFICATION_MODEL_PUSH_NOTIFICATION_SERVICE_H_
+
+#import "ios/chrome/browser/push_notification/push_notification_service.h"
+
+#endif  // IOS_CHROME_BROWSER_PUSH_NOTIFICATION_MODEL_PUSH_NOTIFICATION_SERVICE_H_
diff --git a/ios/chrome/browser/sessions/BUILD.gn b/ios/chrome/browser/sessions/BUILD.gn
index 0a0da6f..2dbdb49 100644
--- a/ios/chrome/browser/sessions/BUILD.gn
+++ b/ios/chrome/browser/sessions/BUILD.gn
@@ -200,13 +200,34 @@
   ]
 }
 
+source_set("legacy_session_restoration_service") {
+  sources = [
+    "legacy_session_restoration_service.h",
+    "legacy_session_restoration_service.mm",
+  ]
+  deps = [
+    ":restoration_agent",
+    ":restoration_observer",
+    ":session_migration",
+    ":session_restoration_service",
+    ":session_service",
+    "//base",
+    "//ios/chrome/browser/shared/model/browser_state",
+    "//ios/web/public",
+    "//ios/web/public/session",
+    "//ios/web/public/session/proto",
+  ]
+}
+
 source_set("session_restoration_service_factory") {
   sources = [
     "session_restoration_service_factory.h",
     "session_restoration_service_factory.mm",
   ]
   deps = [
+    ":legacy_session_restoration_service",
     ":session_restoration_service_impl",
+    ":session_service",
     "//base",
     "//components/keyed_service/ios",
     "//ios/chrome/browser/shared/model/browser",
@@ -304,6 +325,7 @@
 source_set("unit_tests") {
   testonly = true
   sources = [
+    "legacy_session_restoration_service_unittest.mm",
     "proto_util_unittest.cc",
     "session_internal_util_unittest.mm",
     "session_io_request_unittest.mm",
@@ -322,6 +344,7 @@
   ]
   deps = [
     ":fake",
+    ":legacy_session_restoration_service",
     ":resources_unit_tests",
     ":restoration_agent",
     ":restoration_observer",
@@ -352,7 +375,9 @@
     "//ios/chrome/browser/signin",
     "//ios/chrome/browser/signin:test_support",
     "//ios/chrome/browser/tabs/model:features",
+    "//ios/chrome/browser/web:feature_flags",
     "//ios/chrome/browser/web:web_internal",
+    "//ios/chrome/browser/web/session_state",
     "//ios/chrome/test:test_support",
     "//ios/web/common:features",
     "//ios/web/common:user_agent",
diff --git a/ios/chrome/browser/sessions/legacy_session_restoration_service.h b/ios/chrome/browser/sessions/legacy_session_restoration_service.h
new file mode 100644
index 0000000..ecd08839
--- /dev/null
+++ b/ios/chrome/browser/sessions/legacy_session_restoration_service.h
@@ -0,0 +1,72 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_SESSIONS_LEGACY_SESSION_RESTORATION_SERVICE_H_
+#define IOS_CHROME_BROWSER_SESSIONS_LEGACY_SESSION_RESTORATION_SERVICE_H_
+
+#include <set>
+
+#include "base/observer_list.h"
+#include "base/sequence_checker.h"
+#include "ios/chrome/browser/sessions/session_restoration_observer.h"
+#include "ios/chrome/browser/sessions/session_restoration_service.h"
+
+@class SessionServiceIOS;
+
+// Implementation of SessionRestorationService that wraps the legacy API
+// (SessionRestorationBrowserAgent and SessionServiceIOS). Used when the
+// feature is disabled.
+//
+// TODO(crbug.com/1383087): Remove when the feature is fully launched.
+class LegacySessionRestorationService final
+    : public SessionRestorationService,
+      public SessionRestorationObserver {
+ public:
+  LegacySessionRestorationService(bool is_pinned_tabs_enabled,
+                                  SessionServiceIOS* session_service_ios);
+
+  ~LegacySessionRestorationService() final;
+
+  // KeyedService implementation.
+  void Shutdown() final;
+
+  // SessionRestorationService implementation.
+  void AddObserver(SessionRestorationObserver* observer) final;
+  void RemoveObserver(SessionRestorationObserver* observer) final;
+  void SaveSessions() final;
+  void ScheduleSaveSessions() final;
+  void SetSessionID(Browser* browser, const std::string& identifier) final;
+  void LoadSession(Browser* browser) final;
+  void Disconnect(Browser* browser) final;
+  std::unique_ptr<web::WebState> CreateUnrealizedWebState(
+      Browser* browser,
+      web::proto::WebStateStorage storage) final;
+  void InvokeClosureWhenBackgroundProcessingDone(
+      base::OnceClosure closure) final;
+
+  // SessionRestorationObserver implementation.
+  void WillStartSessionRestoration(Browser* browser) final;
+  void SessionRestorationFinished(
+      Browser* browser,
+      const std::vector<web::WebState*>& restored_web_states) final;
+
+ private:
+  SEQUENCE_CHECKER(sequence_checker_);
+
+  // Observer list.
+  base::ObserverList<SessionRestorationObserver, true> observers_;
+
+  // Whether pinned tabs support is enabled (injected via the constructor to
+  // allow easily testing code controlled by this boolean independently of
+  // whether the feature is enabled in the application).
+  const bool is_pinned_tabs_enabled_;
+
+  // Service used to schedule and save the data to storage.
+  __strong SessionServiceIOS* session_service_ios_ = nil;
+
+  // Set of observed Browser objects.
+  std::set<Browser*> browsers_;
+};
+
+#endif  // IOS_CHROME_BROWSER_SESSIONS_LEGACY_SESSION_RESTORATION_SERVICE_H_
diff --git a/ios/chrome/browser/sessions/legacy_session_restoration_service.mm b/ios/chrome/browser/sessions/legacy_session_restoration_service.mm
new file mode 100644
index 0000000..50bb8e78
--- /dev/null
+++ b/ios/chrome/browser/sessions/legacy_session_restoration_service.mm
@@ -0,0 +1,131 @@
+// 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.
+
+#import "ios/chrome/browser/sessions/legacy_session_restoration_service.h"
+
+#import "base/check.h"
+#import "base/containers/contains.h"
+#import "base/functional/callback.h"
+#import "base/strings/sys_string_conversions.h"
+#import "ios/chrome/browser/sessions/session_restoration_browser_agent.h"
+#import "ios/chrome/browser/sessions/session_service_ios.h"
+#import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
+#import "ios/web/public/session/crw_session_storage.h"
+#import "ios/web/public/session/proto/storage.pb.h"
+#import "ios/web/public/web_state.h"
+
+LegacySessionRestorationService::LegacySessionRestorationService(
+    bool is_pinned_tabs_enabled,
+    SessionServiceIOS* session_service_ios)
+    : is_pinned_tabs_enabled_(is_pinned_tabs_enabled),
+      session_service_ios_(session_service_ios) {
+  DCHECK(session_service_ios_);
+}
+
+LegacySessionRestorationService::~LegacySessionRestorationService() {}
+
+void LegacySessionRestorationService::Shutdown() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(browsers_.empty()) << "Disconnect() must be called for all Browser";
+}
+
+void LegacySessionRestorationService::AddObserver(
+    SessionRestorationObserver* observer) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  observers_.AddObserver(observer);
+}
+
+void LegacySessionRestorationService::RemoveObserver(
+    SessionRestorationObserver* observer) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  observers_.RemoveObserver(observer);
+}
+
+void LegacySessionRestorationService::SaveSessions() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  for (Browser* browser : browsers_) {
+    SessionRestorationBrowserAgent::FromBrowser(browser)->SaveSession(
+        /* immediately*/ true);
+  }
+}
+
+void LegacySessionRestorationService::ScheduleSaveSessions() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  for (Browser* browser : browsers_) {
+    SessionRestorationBrowserAgent::FromBrowser(browser)->SaveSession(
+        /* immediately*/ false);
+  }
+}
+
+void LegacySessionRestorationService::SetSessionID(
+    Browser* browser,
+    const std::string& identifier) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(!base::Contains(browsers_, browser));
+  browsers_.insert(browser);
+
+  // Create the SessionRestorationBrowserAgent for browser.
+  SessionRestorationBrowserAgent::CreateForBrowser(
+      browser, session_service_ios_, is_pinned_tabs_enabled_);
+
+  SessionRestorationBrowserAgent* browser_agent =
+      SessionRestorationBrowserAgent::FromBrowser(browser);
+
+  browser_agent->AddObserver(this);
+  browser_agent->SetSessionID(base::SysUTF8ToNSString(identifier));
+}
+
+void LegacySessionRestorationService::LoadSession(Browser* browser) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(base::Contains(browsers_, browser));
+  SessionRestorationBrowserAgent::FromBrowser(browser)->RestoreSession();
+}
+
+void LegacySessionRestorationService::Disconnect(Browser* browser) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(base::Contains(browsers_, browser));
+  browsers_.erase(browser);
+
+  SessionRestorationBrowserAgent* browser_agent =
+      SessionRestorationBrowserAgent::FromBrowser(browser);
+
+  browser_agent->SaveSession(/* immediately */ true);
+  browser_agent->RemoveObserver(this);
+
+  // Destroy the SessionRestorationBrowserAgent for browser.
+  SessionRestorationBrowserAgent::RemoveFromBrowser(browser);
+}
+
+std::unique_ptr<web::WebState>
+LegacySessionRestorationService::CreateUnrealizedWebState(
+    Browser* browser,
+    web::proto::WebStateStorage storage) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return web::WebState::CreateWithStorageSession(
+      web::WebState::CreateParams(browser->GetBrowserState()),
+      [[CRWSessionStorage alloc] initWithProto:storage]);
+}
+
+void LegacySessionRestorationService::InvokeClosureWhenBackgroundProcessingDone(
+    base::OnceClosure closure) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  [session_service_ios_ shutdownWithClosure:std::move(closure)];
+}
+
+void LegacySessionRestorationService::WillStartSessionRestoration(
+    Browser* browser) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  for (SessionRestorationObserver& observer : observers_) {
+    observer.WillStartSessionRestoration(browser);
+  }
+}
+
+void LegacySessionRestorationService::SessionRestorationFinished(
+    Browser* browser,
+    const std::vector<web::WebState*>& restored_web_states) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  for (SessionRestorationObserver& observer : observers_) {
+    observer.SessionRestorationFinished(browser, restored_web_states);
+  }
+}
diff --git a/ios/chrome/browser/sessions/legacy_session_restoration_service_unittest.mm b/ios/chrome/browser/sessions/legacy_session_restoration_service_unittest.mm
new file mode 100644
index 0000000..f42afc8
--- /dev/null
+++ b/ios/chrome/browser/sessions/legacy_session_restoration_service_unittest.mm
@@ -0,0 +1,995 @@
+// 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.
+
+#import "ios/chrome/browser/sessions/legacy_session_restoration_service.h"
+
+#import <map>
+#import <set>
+
+#import "base/check_op.h"
+#import "base/containers/span.h"
+#import "base/files/file_enumerator.h"
+#import "base/files/file_util.h"
+#import "base/files/scoped_temp_dir.h"
+#import "base/functional/bind.h"
+#import "base/run_loop.h"
+#import "base/scoped_multi_source_observation.h"
+#import "base/strings/stringprintf.h"
+#import "base/test/metrics/histogram_tester.h"
+#import "base/test/scoped_feature_list.h"
+#import "base/time/time.h"
+#import "ios/chrome/browser/sessions/session_constants.h"
+#import "ios/chrome/browser/sessions/session_internal_util.h"
+#import "ios/chrome/browser/sessions/session_loading.h"
+#import "ios/chrome/browser/sessions/session_service_ios.h"
+#import "ios/chrome/browser/sessions/session_window_ios.h"
+#import "ios/chrome/browser/sessions/test_session_restoration_observer.h"
+#import "ios/chrome/browser/shared/model/browser/test/test_browser.h"
+#import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h"
+#import "ios/chrome/browser/shared/model/web_state_list/test/fake_web_state_list_delegate.h"
+#import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h"
+#import "ios/chrome/browser/shared/model/web_state_list/web_state_opener.h"
+#import "ios/chrome/browser/web/chrome_web_client.h"
+#import "ios/chrome/browser/web/features.h"
+#import "ios/chrome/browser/web/session_state/web_session_state_tab_helper.h"
+#import "ios/web/common/user_agent.h"
+#import "ios/web/public/navigation/navigation_manager.h"
+#import "ios/web/public/navigation/navigation_util.h"
+#import "ios/web/public/navigation/referrer.h"
+#import "ios/web/public/test/scoped_testing_web_client.h"
+#import "ios/web/public/test/web_task_environment.h"
+#import "ios/web/public/web_state.h"
+#import "ios/web/public/web_state_observer.h"
+#import "testing/platform_test.h"
+#import "ui/base/page_transition_types.h"
+#import "ui/base/window_open_disposition.h"
+#import "url/gurl.h"
+
+// To get access to web::features::kEnableSessionSerializationOptimizations.
+// TODO(crbug.com/1383087): remove once the feature is fully launched.
+#import "ios/web/common/features.h"
+
+namespace {
+
+// Set of FilePath.
+using FilePathSet = std::set<base::FilePath>;
+
+// Delay before saving the session to storage during test. This makes the
+// test independent from the delay used in production (i.e. does not need
+// to know how long to skip ahead with
+constexpr base::TimeDelta kSaveDelay = base::Seconds(1);
+
+// Identifier used for the Browser under test.
+const char kIdentifier0[] = "browser0";
+const char kIdentifier1[] = "browser1";
+
+// List of URLs that are loaded in the session.
+constexpr std::string_view kURLs[] = {
+    "chrome://version",
+    "chrome://flags",
+    "chrome://credits",
+};
+
+// URL and title used to create an unrealized WebState.
+const char kURL[] = "https://example.com";
+const char16_t kTitle[] = u"Example Domain";
+
+// Scoped observer template.
+template <typename Source, typename Observer>
+class ScopedObserver : public Observer {
+ public:
+  template <typename... Args>
+  ScopedObserver(Args&&... args) : Observer(std::forward<Args>(args)...) {}
+
+  // Register self as observing `source`.
+  void Observe(Source* source) { observation_.AddObservation(source); }
+
+  // Unregister self from any observed sources.
+  void Reset() { observation_.RemoveAllObservations(); }
+
+ private:
+  base::ScopedMultiSourceObservation<Source, Observer> observation_{this};
+};
+
+// A WebStateObserver that invokes a callback when DidFinishNavigation() happen.
+class TestWebStateObserver : public web::WebStateObserver {
+ public:
+  TestWebStateObserver(const base::RepeatingClosure& closure)
+      : closure_(closure) {}
+
+  // web::WebStateObserver implementation.
+  void DidFinishNavigation(web::WebState* web_state,
+                           web::NavigationContext* context) override {
+    closure_.Run();
+  }
+
+ private:
+  base::RepeatingClosure closure_;
+};
+
+// Scoped variant of observers.
+using ScopedTestSessionRestorationObserver =
+    ScopedObserver<SessionRestorationService, TestSessionRestorationObserver>;
+using ScopedTestWebStateObserver =
+    ScopedObserver<web::WebState, TestWebStateObserver>;
+
+// Class that can be used to detect files that are modified.
+class FileModificationTracker {
+ public:
+  FileModificationTracker() = default;
+
+  // Records all existing files below `root` and their timestamp. Used to
+  // detect created or updated files later in `ModifiedFiles(...)`.
+  void Start(const base::FilePath& path) { snapshot_ = EnumerateFiles(path); }
+
+  // Reports all created or updated files in `path` since call to `Start(...)`.
+  FilePathSet ModifiedFiles(const base::FilePath& path) const {
+    FilePathSet result;
+    for (const auto& [name, time] : EnumerateFiles(path)) {
+      auto iterator = snapshot_.find(name);
+      if (iterator == snapshot_.end() || iterator->second != time) {
+        result.insert(name);
+      }
+    }
+    return result;
+  }
+
+  // Reports all deleted files in `path` since call to `Start(...)`.
+  FilePathSet DeletedFiles(const base::FilePath& path) const {
+    FilePathSet result;
+    PathToTimeMap state = EnumerateFiles(path);
+    for (const auto& [name, _] : snapshot_) {
+      if (!base::Contains(state, name)) {
+        result.insert(name);
+      }
+    }
+    return result;
+  }
+
+ private:
+  using PathToTimeMap = std::map<base::FilePath, base::Time>;
+
+  // Returns a mapping of files to their last modified time below `path`.
+  PathToTimeMap EnumerateFiles(const base::FilePath& path) const {
+    PathToTimeMap result;
+
+    base::FileEnumerator e(path, true, base::FileEnumerator::FileType::FILES);
+    for (base::FilePath name = e.Next(); !name.empty(); name = e.Next()) {
+      // Workaround for the fact that base::FileEnumerator::FileInfo drops the
+      // sub-second precision when using GetLastModifiedTime() even when the
+      // data is available. See https://crbug.com/1491766 for details.
+      base::File::Info info;
+      info.FromStat(e.GetInfo().stat());
+
+      result.insert(std::make_pair(name, info.last_modified));
+    }
+
+    return result;
+  }
+
+  PathToTimeMap snapshot_;
+};
+
+// Structure storing a WebState and whether the native session is supposed
+// to be available. Used by ExpectedStorageFilesForWebStates.
+struct WebStateReference {
+  const web::WebState* web_state = nullptr;
+  bool is_native_session_available = false;
+};
+
+// A WebStateListDelegate that creates the WebSessionStateTabHelper for
+// WebState inserted in the WebStateList (as this is required by the
+// LegacySessionRestorationService).
+class TestWebStateListDelegate final : public FakeWebStateListDelegate {
+ public:
+  void WillAddWebState(web::WebState* web_state) final {
+    if (web::UseNativeSessionRestorationCache()) {
+      WebSessionStateTabHelper::CreateForWebState(web_state);
+    }
+  }
+};
+
+// Returns the storage file for `references` in `session_dir`.
+FilePathSet ExpectedStorageFilesForWebStates(
+    const base::FilePath& storage_dir,
+    const std::string& identifier,
+    bool expect_session_metadata_storage,
+    const std::vector<WebStateReference>& references) {
+  FilePathSet result;
+  if (expect_session_metadata_storage) {
+    result.insert(storage_dir.Append(kLegacySessionsDirname)
+                      .Append(identifier)
+                      .Append(kLegacySessionFilename));
+  }
+
+  if (web::UseNativeSessionRestorationCache()) {
+    const base::FilePath web_sessions_dir =
+        storage_dir.Append(kLegacyWebSessionsDirname);
+    for (const WebStateReference& reference : references) {
+      if (reference.is_native_session_available) {
+        result.insert(web_sessions_dir.Append(base::StringPrintf(
+            "%08u", reference.web_state->GetUniqueIdentifier().identifier())));
+      }
+    }
+  }
+
+  return result;
+}
+
+// Returns the path of storage file to `browser` in `session_dir`.
+FilePathSet ExpectedStorageFilesForBrowser(const base::FilePath& storage_dir,
+                                           const std::string& identifier,
+                                           Browser* browser) {
+  std::vector<WebStateReference> references;
+  WebStateList* web_state_list = browser->GetWebStateList();
+  for (int index = 0; index < web_state_list->count(); ++index) {
+    references.push_back(WebStateReference{
+        .web_state = web_state_list->GetWebStateAt(index),
+        .is_native_session_available = true,
+    });
+  }
+  return ExpectedStorageFilesForWebStates(storage_dir, identifier, true,
+                                          references);
+}
+
+// Set union.
+FilePathSet operator+(const FilePathSet& lhs, const FilePathSet& rhs) {
+  FilePathSet result;
+  result.insert(lhs.begin(), lhs.end());
+  result.insert(rhs.begin(), rhs.end());
+  return result;
+}
+
+// Returns a closure that expects to be call `n` times and that will invoke
+// `closure` on the n-th invocation.
+base::RepeatingClosure ExpectNCall(base::RepeatingClosure closure, size_t n) {
+  __block size_t counter = 0;
+  return base::BindRepeating(^{
+    DCHECK_LT(counter, n);
+    if (++counter == n) {
+      closure.Run();
+    }
+  });
+}
+
+}  // namespace
+
+// The fixture used to test LegacySessionRestorationService.
+//
+// It uses a TaskEnvironment mocking the time to allow to easily control when
+// LegacySessionRestorationService's task to save data to storage will execute.
+class LegacySessionRestorationServiceTest : public PlatformTest {
+ public:
+  LegacySessionRestorationServiceTest() {
+    // Disable the feature. Needs to happen before the threads are created.
+    scoped_feature_list_.InitAndDisableFeature(
+        web::features::kEnableSessionSerializationOptimizations);
+
+    // Use the ChromeWebClient as the test tries to load chrome:// URLs.
+    scoped_web_client_ = std::make_unique<web::ScopedTestingWebClient>(
+        std::make_unique<ChromeWebClient>());
+
+    // Configure a WebTaskEnvironment with mocked time to be able to
+    // fast-forward time and skip the delay before saving the data.
+    web_task_environment_ = std::make_unique<web::WebTaskEnvironment>(
+        web::WebTaskEnvironment::Options::DEFAULT,
+        base::test::TaskEnvironment::TimeSource::MOCK_TIME);
+
+    // Create a test ChromeBrowserState and an object to track the files
+    // that are created by the session restoration service operations.
+    browser_state_ = TestChromeBrowserState::Builder().Build();
+    file_tracker_.Start(browser_state_->GetStatePath());
+
+    SessionServiceIOS* session_service_ios = [[SessionServiceIOS alloc]
+        initWithSaveDelay:kSaveDelay
+               taskRunner:base::SequencedTaskRunner::GetCurrentDefault()];
+
+    // Create the service, force enabling the pinned tab support (since
+    // the code using the `is_pinned_tabs_enabled` is tested by the
+    // deserialization code and does not need to be tested again here).
+    service_ = std::make_unique<LegacySessionRestorationService>(
+        /* is_pinned_tabs_enabled */ true, session_service_ios);
+  }
+
+  ~LegacySessionRestorationServiceTest() override { service_->Shutdown(); }
+
+  // Returns the ChromeBrowserState used for tests.
+  ChromeBrowserState* browser_state() { return browser_state_.get(); }
+
+  // Returns the service under test.
+  SessionRestorationService* service() { return service_.get(); }
+
+  // Returns the BrowserState's storage path.
+  base::FilePath storage_path() { return browser_state_->GetStatePath(); }
+
+  // Inserts WebStates into `browser` each one loading a new URL from `urls`
+  // and wait until all the WebStates are done with the navigation.
+  void InsertTabsWithUrls(Browser& browser,
+                          base::span<const std::string_view> urls) {
+    base::RunLoop run_loop;
+    ScopedTestWebStateObserver web_state_observer(
+        ExpectNCall(run_loop.QuitClosure(), std::size(urls)));
+
+    WebStateList* web_state_list = browser.GetWebStateList();
+    for (std::string_view url : urls) {
+      std::unique_ptr<web::WebState> web_state =
+          web::WebState::Create(web::WebState::CreateParams(browser_state()));
+
+      web_state_observer.Observe(web_state.get());
+
+      // The view of the WebState needs to be created before the navigation
+      // is really executed.
+      std::ignore = web_state->GetView();
+      web_state->GetNavigationManager()->LoadURLWithParams(
+          web::NavigationManager::WebLoadParams(GURL(url)));
+
+      web_state_list->InsertWebState(
+          WebStateList::kInvalidIndex, std::move(web_state),
+          WebStateList::INSERT_ACTIVATE, WebStateOpener());
+    }
+
+    // Wait for the navigation to commit.
+    run_loop.Run();
+  }
+
+  // Wait until all task posted on the background sequence are complete.
+  void WaitForBackgroundTaskComplete() {
+    base::RunLoop run_loop;
+    service_->InvokeClosureWhenBackgroundProcessingDone(run_loop.QuitClosure());
+    run_loop.Run();
+  }
+
+  // Wait until the save delay expired and then for all background task
+  // to complete.
+  void WaitForSessionSaveComplete() {
+    // Fast forward the time to allow any timer to expire (and thus the
+    // delayed save to be scheduled).
+    web_task_environment_->FastForwardBy(kSaveDelay);
+
+    WaitForBackgroundTaskComplete();
+  }
+
+  // Take a snapshot of the existing files.
+  void SnapshotFiles() { file_tracker_.Start(browser_state_->GetStatePath()); }
+
+  // Returns the list of modified files.
+  FilePathSet ModifiedFiles() const {
+    return file_tracker_.ModifiedFiles(browser_state_->GetStatePath());
+  }
+
+  // Returns the list of deleted files.
+  FilePathSet DeletedFiles() const {
+    return file_tracker_.DeletedFiles(browser_state_->GetStatePath());
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+  FileModificationTracker file_tracker_;
+
+  std::unique_ptr<web::ScopedTestingWebClient> scoped_web_client_;
+  std::unique_ptr<web::WebTaskEnvironment> web_task_environment_;
+
+  std::unique_ptr<TestChromeBrowserState> browser_state_;
+  std::unique_ptr<LegacySessionRestorationService> service_;
+};
+
+// Tests that adding and removing observer works correctly.
+TEST_F(LegacySessionRestorationServiceTest, ObserverRegistration) {
+  ScopedTestSessionRestorationObserver observer;
+  ASSERT_FALSE(observer.IsInObserverList());
+
+  // Check that registering/unregistering the observer works.
+  observer.Observe(service());
+  EXPECT_TRUE(observer.IsInObserverList());
+
+  observer.Reset();
+  EXPECT_FALSE(observer.IsInObserverList());
+}
+
+// Tests that SetSessionID does not load the session.
+TEST_F(LegacySessionRestorationServiceTest, SetSessionID) {
+  ScopedTestSessionRestorationObserver observer;
+  observer.Observe(service());
+
+  // Check that calling SetSessionID() does not load the session.
+  TestBrowser browser = TestBrowser(
+      browser_state(), std::make_unique<TestWebStateListDelegate>());
+  service()->SetSessionID(&browser, kIdentifier0);
+  EXPECT_FALSE(observer.restore_started());
+
+  // Check that calling Disconnect() force save the session even if there
+  // are no changes.
+  service()->Disconnect(&browser);
+  WaitForSessionSaveComplete();
+
+  // Check that no session file was written to disk.
+  EXPECT_EQ(ModifiedFiles(), ExpectedStorageFilesForBrowser(
+                                 storage_path(), kIdentifier0, &browser));
+}
+
+// Tests that LoadSession correctly loads the session from disk.
+TEST_F(LegacySessionRestorationServiceTest, LoadSession) {
+  ScopedTestSessionRestorationObserver observer;
+  observer.Observe(service());
+
+  // Check that when a Browser is modified, the changes are reflected to the
+  // storage after a delay.
+  {
+    TestBrowser browser = TestBrowser(
+        browser_state(), std::make_unique<TestWebStateListDelegate>());
+    service()->SetSessionID(&browser, kIdentifier0);
+    EXPECT_FALSE(observer.restore_started());
+
+    // Insert a few WebState in the Browser's WebStateList.
+    InsertTabsWithUrls(browser, base::make_span(kURLs));
+
+    // Check that the session was written to disk.
+    WaitForSessionSaveComplete();
+    EXPECT_EQ(ModifiedFiles(), ExpectedStorageFilesForBrowser(
+                                   storage_path(), kIdentifier0, &browser));
+
+    // Disconnect the Browser before destroying it. The service should no
+    // longer track it and any modification should not be reflected.
+    service()->Disconnect(&browser);
+
+    // Disconnecting the Browser will force save, so wait for the save to
+    // complete and then snapshot the files.
+    WaitForBackgroundTaskComplete();
+    EXPECT_EQ(ModifiedFiles(), ExpectedStorageFilesForBrowser(
+                                   storage_path(), kIdentifier0, &browser));
+
+    // Check that closing the all the tabs after disconnecting the Browser
+    // does not cause the session to be saved again nor deleted.
+    SnapshotFiles();
+    browser.GetWebStateList()->CloseAllWebStates(WebStateList::CLOSE_NO_FLAGS);
+
+    WaitForSessionSaveComplete();
+    EXPECT_EQ(DeletedFiles(), FilePathSet{});
+    EXPECT_EQ(ModifiedFiles(), FilePathSet{});
+  }
+
+  // Check that the session can be reloaded and that it contains the same
+  // state as when it was saved.
+  {
+    TestBrowser browser = TestBrowser(
+        browser_state(), std::make_unique<TestWebStateListDelegate>());
+    service()->SetSessionID(&browser, kIdentifier0);
+    EXPECT_FALSE(observer.restore_started());
+
+    // Perform session restore, and check that the expected WebState have
+    // been recreated with the correct navigation history.
+    service()->LoadSession(&browser);
+
+    EXPECT_TRUE(observer.restore_started());
+    EXPECT_EQ(observer.restored_web_states_count(),
+              static_cast<int>(std::size(kURLs)));
+
+    WebStateList* web_state_list = browser.GetWebStateList();
+    EXPECT_EQ(web_state_list->count(), static_cast<int>(std::size(kURLs)));
+    EXPECT_EQ(web_state_list->active_index(), web_state_list->count() - 1);
+    for (int index = 0; index < web_state_list->count(); ++index) {
+      web::WebState* web_state = web_state_list->GetWebStateAt(index);
+      EXPECT_EQ(web_state->GetLastCommittedURL(), GURL(kURLs[index]));
+    }
+
+    // Disconnect the Browser before destroying it.
+    service()->Disconnect(&browser);
+  }
+}
+
+// Tests that LoadSession succeed even if the session is empty.
+TEST_F(LegacySessionRestorationServiceTest, LoadSession_EmptySession) {
+  ScopedTestSessionRestorationObserver observer;
+  observer.Observe(service());
+
+  // Write an empty session.
+  SessionWindowIOS* session =
+      [[SessionWindowIOS alloc] initWithSessions:@[] selectedIndex:NSNotFound];
+
+  const base::FilePath session_path = storage_path()
+                                          .Append(kLegacySessionsDirname)
+                                          .Append(kIdentifier0)
+                                          .Append(kLegacySessionFilename);
+  EXPECT_TRUE(ios::sessions::WriteSessionWindow(session_path, session));
+
+  // Check that the session can be loaded even if non-existent and that the
+  // Browser is unmodified (but the observers notified).
+  {
+    TestBrowser browser = TestBrowser(
+        browser_state(), std::make_unique<TestWebStateListDelegate>());
+    service()->SetSessionID(&browser, kIdentifier0);
+    EXPECT_FALSE(observer.restore_started());
+
+    // Check that loading the sessions succeed.
+    service()->LoadSession(&browser);
+
+    EXPECT_TRUE(observer.restore_started());
+    EXPECT_EQ(observer.restored_web_states_count(), 0);
+
+    // Disconnect the Browser before destroying it.
+    service()->Disconnect(&browser);
+  }
+}
+
+// Tests that LoadSession succeed even if the session does not exist.
+TEST_F(LegacySessionRestorationServiceTest, LoadSession_MissingSession) {
+  ScopedTestSessionRestorationObserver observer;
+  observer.Observe(service());
+
+  // Check that the session can be loaded even if non-existent and that the
+  // Browser is unmodified (but the observers notified).
+  {
+    TestBrowser browser = TestBrowser(
+        browser_state(), std::make_unique<TestWebStateListDelegate>());
+    service()->SetSessionID(&browser, kIdentifier0);
+    EXPECT_FALSE(observer.restore_started());
+
+    // Check that loading the sessions succeed, even if there is no session.
+    service()->LoadSession(&browser);
+
+    EXPECT_TRUE(observer.restore_started());
+    EXPECT_EQ(observer.restored_web_states_count(), 0);
+
+    // Disconnect the Browser before destroying it.
+    service()->Disconnect(&browser);
+  }
+}
+
+// Tests that the service only saves the session of modified Browser.
+TEST_F(LegacySessionRestorationServiceTest, SaveSessionOfModifiedBrowser) {
+  // Register multiple Browser and modify one of them. Check that
+  // only data for the modified Browser is written to disk.
+  TestBrowser browser0 = TestBrowser(
+      browser_state(), std::make_unique<TestWebStateListDelegate>());
+  TestBrowser browser1 = TestBrowser(
+      browser_state(), std::make_unique<TestWebStateListDelegate>());
+  service()->SetSessionID(&browser0, kIdentifier0);
+  service()->SetSessionID(&browser1, kIdentifier1);
+
+  // Insert a few WebState in browser1's WebStateList.
+  InsertTabsWithUrls(browser1, base::make_span(kURLs));
+
+  // Check that only browser1's session was written to disk.
+  WaitForSessionSaveComplete();
+  EXPECT_EQ(ModifiedFiles(), ExpectedStorageFilesForBrowser(
+                                 storage_path(), kIdentifier1, &browser1));
+
+  // Disconnect the Browser before destroying it.
+  service()->Disconnect(&browser1);
+  service()->Disconnect(&browser0);
+}
+
+// Tests that the service only save content that has changed.
+TEST_F(LegacySessionRestorationServiceTest,
+       SaveSessionChangesOnlyRequiredFiles) {
+  // Create a Browser and add a few WebStates to it.
+  TestBrowser browser = TestBrowser(
+      browser_state(), std::make_unique<TestWebStateListDelegate>());
+  service()->SetSessionID(&browser, kIdentifier0);
+  InsertTabsWithUrls(browser, base::make_span(kURLs));
+
+  // Check that the session was written to disk.
+  WaitForSessionSaveComplete();
+  EXPECT_EQ(ModifiedFiles(), ExpectedStorageFilesForBrowser(
+                                 storage_path(), kIdentifier0, &browser));
+
+  // Record the list of existing files and their timestamp.
+  SnapshotFiles();
+
+  // Change the active WebState, and mark the new WebState as visited. This
+  // should result in saving the session metadata (due to the change in the
+  // WebStateList).
+  ASSERT_NE(browser.GetWebStateList()->active_index(), 0);
+  browser.GetWebStateList()->ActivateWebStateAt(0);
+
+  // Check that session metadata storage file and the active WebState storage
+  // files are eventually saved.
+  WaitForSessionSaveComplete();
+  EXPECT_EQ(ModifiedFiles(),
+            ExpectedStorageFilesForWebStates(
+                storage_path(), kIdentifier0,
+                /* expect_session_metadata_storage */ true, {}));
+
+  // Disconnect the Browser before destroying it.
+  service()->Disconnect(&browser);
+}
+
+// Tests that the service correctly support moving "unrealized" tabs between
+// Browsers and that this results in a copy of the moved WebState's storage.
+TEST_F(LegacySessionRestorationServiceTest, AdoptUnrealizedWebStateOnMove) {
+  // In order to have unrealized WebState in the Browser, create a Browser,
+  // add some WebState, wait for the session to be serialized. The session
+  // can then be loaed to get unrealized WebStates.
+  {
+    TestBrowser browser = TestBrowser(
+        browser_state(), std::make_unique<TestWebStateListDelegate>());
+    service()->SetSessionID(&browser, kIdentifier0);
+
+    // Insert a few WebState in the Browser's WebStateList.
+    InsertTabsWithUrls(browser, base::make_span(kURLs));
+
+    // Check that the session was written to disk.
+    WaitForSessionSaveComplete();
+    EXPECT_EQ(ModifiedFiles(), ExpectedStorageFilesForBrowser(
+                                   storage_path(), kIdentifier0, &browser));
+
+    // Disconnect the Browser before destroying it.
+    service()->Disconnect(&browser);
+
+    // Check that closing the all the tabs after disconnecting the Browser
+    // does not delete the sesion.
+    WaitForSessionSaveComplete();
+    EXPECT_EQ(ModifiedFiles(), ExpectedStorageFilesForBrowser(
+                                   storage_path(), kIdentifier0, &browser));
+  }
+
+  // Load the session created before, and then move the tabs from the first
+  // browser to the second one. Check that the session files have been copied.
+  TestBrowser browser0 = TestBrowser(
+      browser_state(), std::make_unique<TestWebStateListDelegate>());
+  TestBrowser browser1 = TestBrowser(
+      browser_state(), std::make_unique<TestWebStateListDelegate>());
+  service()->SetSessionID(&browser0, kIdentifier0);
+  service()->SetSessionID(&browser1, kIdentifier1);
+
+  // Load the session in `browser0` and check that the expected number of tabs
+  // are present and that the inactive tabs are not realized.
+  service()->LoadSession(&browser0);
+  service()->LoadSession(&browser1);
+
+  // Record the list of existing files and their timestamp.
+  SnapshotFiles();
+
+  WebStateList* list0 = browser0.GetWebStateList();
+  WebStateList* list1 = browser1.GetWebStateList();
+  ASSERT_EQ(list0->count(), static_cast<int>(std::size(kURLs)));
+  ASSERT_EQ(list1->count(), 0);
+
+  // Check that the WebState are not realized.
+  for (int index = 0; index < list0->count(); ++index) {
+    web::WebState* web_state = list0->GetWebStateAt(index);
+    EXPECT_FALSE(web_state->IsRealized());
+  }
+
+  // Move all tabs from browser0 to browser1 and check that this results in
+  // the copy of the WebState's storage from browser0 to browser1 session
+  // directory.
+  //
+  // Start by moving the inactive tabs, then move all the active tabs. The
+  // move is done in reverse order to simplify the iteration (this allows
+  // skipping the active_index during the iteration without going out of
+  // range).
+  const int old_count = list0->count();
+  const int old_active_index = list0->active_index();
+  ASSERT_EQ(list1->active_index(), WebStateList::kInvalidIndex);
+  for (int index = 0; index < old_count; ++index) {
+    const int reverse_index = old_count - 1 - index;
+    if (reverse_index == old_active_index) {
+      continue;
+    }
+
+    list1->InsertWebState(0, list0->DetachWebStateAt(reverse_index),
+                          WebStateList::INSERT_FORCE_INDEX, WebStateOpener());
+    ASSERT_EQ(list1->active_index(), WebStateList::kInvalidIndex);
+  }
+
+  ASSERT_EQ(list0->count(), 1);
+  std::unique_ptr<web::WebState> web_state = list0->DetachWebStateAt(0);
+  list1->InsertWebState(
+      old_active_index, std::move(web_state),
+      WebStateList::INSERT_FORCE_INDEX | WebStateList::INSERT_ACTIVATE,
+      WebStateOpener());
+
+  ASSERT_EQ(list0->count(), 0);
+  ASSERT_EQ(list1->count(), static_cast<int>(std::size(kURLs)));
+
+  // Check that no files were deleted, the metadata for both session updated
+  // and the WebState's cache session left untouched.
+  WaitForSessionSaveComplete();
+
+  FilePathSet expected_browser0 = ExpectedStorageFilesForWebStates(
+      storage_path(), kIdentifier0,
+      /* expect_session_metadata_storage */ true, {});
+  FilePathSet expected_browser1 = ExpectedStorageFilesForWebStates(
+      storage_path(), kIdentifier1,
+      /* expect_session_metadata_storage */ true, {});
+
+  EXPECT_EQ(ModifiedFiles(), expected_browser0 + expected_browser1);
+
+  // Disconnect the Browser before destroying them.
+  service()->Disconnect(&browser1);
+  service()->Disconnect(&browser0);
+}
+
+// Tests that the service save pending changes on disconnect.
+TEST_F(LegacySessionRestorationServiceTest, SavePendingChangesOnDisconnect) {
+  // Create a Browser and add a few WebStates to it.
+  TestBrowser browser = TestBrowser(
+      browser_state(), std::make_unique<TestWebStateListDelegate>());
+  service()->SetSessionID(&browser, kIdentifier0);
+  InsertTabsWithUrls(browser, base::make_span(kURLs));
+
+  // Inserting the tabs may take more time than the save delay. Always
+  // wait for the state to be saved so that the test is deterministic.
+  WaitForSessionSaveComplete();
+  EXPECT_EQ(ModifiedFiles(), ExpectedStorageFilesForBrowser(
+                                 storage_path(), kIdentifier0, &browser));
+
+  // Record the list of existing files and their timestamp.
+  SnapshotFiles();
+
+  // Modify the Browser which will schedule a session after a delay.
+  {
+    WebStateList* web_state_list = browser.GetWebStateList();
+    const int active_index = web_state_list->active_index();
+    ASSERT_NE(active_index, 0);
+
+    web_state_list->MoveWebStateAt(active_index, 0);
+  }
+
+  // Record the time and check that no file have been saved yet.
+  const base::Time disconnect_time = base::Time::Now();
+  EXPECT_EQ(ModifiedFiles(), FilePathSet{});
+
+  // Disconnect the Browser. This should save the session immediately.
+  service()->Disconnect(&browser);
+
+  // Not using `WaitForSessionSaveComplete()` because we explicitly do
+  // not want to wait for the kSaveDelay timeout.
+  WaitForBackgroundTaskComplete();
+
+  // Check that even though the save delay has not expired, the data still
+  // has been written to disk (because it was scheduled when the Browser
+  // was disconnected as it contained pending changes).
+  EXPECT_LT(base::Time::Now() - disconnect_time, kSaveDelay);
+  EXPECT_EQ(ModifiedFiles(),
+            ExpectedStorageFilesForWebStates(
+                storage_path(), kIdentifier0,
+                /* expect_session_metadata_storage */ true, {}));
+}
+
+// Tests that histograms are correctly recorded.
+TEST_F(LegacySessionRestorationServiceTest, RecordHistograms) {
+  {
+    // Create a Browser and add a few WebStates to it and wait for all
+    // pending scheduled tasks to complete.
+    TestBrowser browser = TestBrowser(
+        browser_state(), std::make_unique<TestWebStateListDelegate>());
+    service()->SetSessionID(&browser, kIdentifier0);
+    InsertTabsWithUrls(browser, base::make_span(kURLs));
+    WaitForSessionSaveComplete();
+
+    // Check that session is saved and histogram is recorded when making
+    // some changes to the Browser's WebStateList (changing the active
+    // index).
+    base::HistogramTester histogram_tester;
+    ASSERT_NE(browser.GetWebStateList()->active_index(), 0);
+    browser.GetWebStateList()->ActivateWebStateAt(0);
+    WaitForSessionSaveComplete();
+
+    // Check that the time spent to record the session was logged.
+    histogram_tester.ExpectTotalCount(
+        "Session.WebStates.SavingTimeOnMainThread", 1);
+
+    // Disconnect the Browser before destroying it.
+    service()->Disconnect(&browser);
+  }
+
+  // Create a Browser.
+  TestBrowser browser = TestBrowser(
+      browser_state(), std::make_unique<TestWebStateListDelegate>());
+  service()->SetSessionID(&browser, kIdentifier0);
+
+  // Load the session and check that the time spent loading was logged.
+  base::HistogramTester histogram_tester;
+  service()->LoadSession(&browser);
+
+  // Check that the expected content was loaded.
+  EXPECT_EQ(browser.GetWebStateList()->count(),
+            static_cast<int>(std::size(kURLs)));
+  histogram_tester.ExpectTotalCount("Session.WebStates.LoadingTimeOnMainThread",
+                                    1);
+
+  // Disconnect the Browser before destroying it.
+  service()->Disconnect(&browser);
+}
+
+// Tests that creating an unrealized WebState succeed and that the data
+// is correctly saved to the disk.
+TEST_F(LegacySessionRestorationServiceTest, CreateUnrealizedWebState) {
+  // Create a Browser.
+  TestBrowser browser = TestBrowser(
+      browser_state(), std::make_unique<TestWebStateListDelegate>());
+  service()->SetSessionID(&browser, kIdentifier0);
+
+  // Create an unrealized WebState.
+  std::unique_ptr<web::WebState> web_state =
+      service()->CreateUnrealizedWebState(
+          &browser,
+          web::CreateWebStateStorage(
+              web::NavigationManager::WebLoadParams(GURL(kURL)), kTitle, false,
+              web::UserAgentType::MOBILE, base::Time::Now()));
+  ASSERT_TRUE(web_state);
+
+  // Record the list of expected files while the pointer to the newly created
+  // WebState is still valid.
+  const FilePathSet expected_files = ExpectedStorageFilesForWebStates(
+      storage_path(), kIdentifier0,
+      /* expect_session_metadata_storage */ true,
+      {WebStateReference{
+          .web_state = web_state.get(),
+          .is_native_session_available = false,
+      }});
+
+  // Insert the WebState into the Browser's WebStateList and then wait for
+  // the session to be saved to storage.
+  browser.GetWebStateList()->InsertWebState(
+      WebStateList::kInvalidIndex, std::move(web_state),
+      WebStateList::InsertionFlags::INSERT_ACTIVATE, WebStateOpener());
+  WaitForSessionSaveComplete();
+
+  // Check that the data for the WebState has been saved to disk.
+  EXPECT_EQ(ModifiedFiles(), expected_files);
+
+  // Disconnect the Browser before destroying it.
+  service()->Disconnect(&browser);
+}
+
+// Tests that calling SaveSessions() can be done at any point in time.
+TEST_F(LegacySessionRestorationServiceTest, SaveSessionsCallableAtAnyTime) {
+  // Check that calling SaveSessions() when no Browser is observed is a no-op.
+  service()->SaveSessions();
+
+  WaitForBackgroundTaskComplete();
+  EXPECT_EQ(ModifiedFiles(), FilePathSet{});
+
+  // Check that calling SaveSessions() when Browser are registered with no
+  // changes updates the session on disk unconditionally.
+  TestBrowser browser0 = TestBrowser(
+      browser_state(), std::make_unique<TestWebStateListDelegate>());
+  TestBrowser browser1 = TestBrowser(
+      browser_state(), std::make_unique<TestWebStateListDelegate>());
+  service()->SetSessionID(&browser0, kIdentifier0);
+  service()->SetSessionID(&browser1, kIdentifier1);
+
+  service()->SaveSessions();
+
+  const FilePathSet expected_session_browser0 =
+      ExpectedStorageFilesForBrowser(storage_path(), kIdentifier0, &browser0);
+
+  const FilePathSet expected_session_browser1 =
+      ExpectedStorageFilesForBrowser(storage_path(), kIdentifier1, &browser1);
+
+  WaitForBackgroundTaskComplete();
+  EXPECT_EQ(ModifiedFiles(),
+            expected_session_browser0 + expected_session_browser1);
+
+  SnapshotFiles();
+
+  // Insert a few WebStage in one of the Browser and wait for the changes
+  // to automatically be saved (this is because loading the pages will
+  // take time and may cause automatically saving the session).
+  {
+    InsertTabsWithUrls(browser0, base::make_span(kURLs));
+    WaitForSessionSaveComplete();
+
+    EXPECT_EQ(ModifiedFiles(), ExpectedStorageFilesForBrowser(
+                                   storage_path(), kIdentifier0, &browser0));
+
+    SnapshotFiles();
+  }
+
+  // Check that making a modification and then calling SaveSessions() will
+  // result in a save immediately, even without waiting for the save delay.
+  ASSERT_NE(browser0.GetWebStateList()->active_index(), 0);
+  browser0.GetWebStateList()->ActivateWebStateAt(0);
+
+  WaitForBackgroundTaskComplete();
+  EXPECT_EQ(ModifiedFiles(), FilePathSet{});
+
+  service()->SaveSessions();
+  WaitForBackgroundTaskComplete();
+  EXPECT_EQ(ModifiedFiles(),
+            expected_session_browser0 + expected_session_browser1);
+
+  SnapshotFiles();
+
+  // Check that Browsers state is saved when they are disconnected.
+  service()->Disconnect(&browser0);
+  service()->Disconnect(&browser1);
+  WaitForBackgroundTaskComplete();
+  EXPECT_EQ(ModifiedFiles(),
+            expected_session_browser0 + expected_session_browser1);
+
+  // Check that calling SaveSessions() when all Browser have been disconnected
+  // is a no-op.
+  SnapshotFiles();
+
+  service()->SaveSessions();
+
+  WaitForBackgroundTaskComplete();
+  EXPECT_EQ(ModifiedFiles(), FilePathSet{});
+}
+
+// Tests that calling ScheduleSaveSessions() is a no-op.
+TEST_F(LegacySessionRestorationServiceTest, ScheduleSaveSessions) {
+  // Check that calling ScheduleSaveSessions() when no Browser is observed
+  // is a no-op.
+  service()->ScheduleSaveSessions();
+
+  WaitForSessionSaveComplete();
+  EXPECT_EQ(ModifiedFiles(), FilePathSet{});
+
+  // Check that calling ScheduleSaveSessions() when Browser are registered
+  // with no changes is a no-op.
+  TestBrowser browser0 = TestBrowser(
+      browser_state(), std::make_unique<TestWebStateListDelegate>());
+  TestBrowser browser1 = TestBrowser(
+      browser_state(), std::make_unique<TestWebStateListDelegate>());
+  service()->SetSessionID(&browser0, kIdentifier0);
+  service()->SetSessionID(&browser1, kIdentifier1);
+
+  service()->ScheduleSaveSessions();
+
+  const FilePathSet expected_session_browser0 =
+      ExpectedStorageFilesForBrowser(storage_path(), kIdentifier0, &browser0);
+
+  const FilePathSet expected_session_browser1 =
+      ExpectedStorageFilesForBrowser(storage_path(), kIdentifier1, &browser1);
+
+  WaitForSessionSaveComplete();
+  EXPECT_EQ(ModifiedFiles(),
+            expected_session_browser0 + expected_session_browser1);
+
+  SnapshotFiles();
+
+  // Insert a few WebStage in one of the Browser and wait for the changes
+  // to automatically be saved (this is because loading the pages will
+  // take time and may cause automatically saving the session).
+  {
+    InsertTabsWithUrls(browser0, base::make_span(kURLs));
+    WaitForSessionSaveComplete();
+
+    EXPECT_EQ(ModifiedFiles(), ExpectedStorageFilesForBrowser(
+                                   storage_path(), kIdentifier0, &browser0));
+
+    SnapshotFiles();
+  }
+
+  // Check that making a modification and then calling ScheduleSaveSessions()
+  // is also a no-op, and that the save will only happen after the save delay
+  // has expired.
+  ASSERT_NE(browser0.GetWebStateList()->active_index(), 0);
+  browser0.GetWebStateList()->ActivateWebStateAt(0);
+
+  WaitForBackgroundTaskComplete();
+  EXPECT_EQ(ModifiedFiles(), FilePathSet{});
+
+  service()->ScheduleSaveSessions();
+  WaitForBackgroundTaskComplete();
+  EXPECT_EQ(ModifiedFiles(), FilePathSet{});
+
+  // Check that the session are saved after waiting to the save delay.
+  WaitForSessionSaveComplete();
+  EXPECT_EQ(ModifiedFiles(),
+            expected_session_browser0 + expected_session_browser1);
+
+  SnapshotFiles();
+
+  // Check that Browsers state is saved when they are disconnected.
+  service()->Disconnect(&browser0);
+  service()->Disconnect(&browser1);
+  WaitForBackgroundTaskComplete();
+  EXPECT_EQ(ModifiedFiles(),
+            expected_session_browser0 + expected_session_browser1);
+
+  SnapshotFiles();
+
+  // Check that calling ScheduleSaveSessions() when all Browser have been
+  // disconnected is a no-op.
+  service()->ScheduleSaveSessions();
+
+  WaitForBackgroundTaskComplete();
+  EXPECT_EQ(ModifiedFiles(), FilePathSet{});
+}
diff --git a/ios/chrome/browser/sessions/session_restoration_browser_agent.mm b/ios/chrome/browser/sessions/session_restoration_browser_agent.mm
index 6523d123..71a3e6b 100644
--- a/ios/chrome/browser/sessions/session_restoration_browser_agent.mm
+++ b/ios/chrome/browser/sessions/session_restoration_browser_agent.mm
@@ -237,9 +237,15 @@
 }
 
 SessionRestorationBrowserAgent::~SessionRestorationBrowserAgent() {
-  // Disconnect the session factory object as it's not granteed that it will be
-  // released before it's referenced by the session service.
+  // Disconnect the session factory object as it's not garanteed that it will
+  // be released before it's referenced by the session service.
   [session_window_ios_factory_ disconnect];
+
+  // If the object is destroyed before the Browser, unregister it from the
+  // ObserverList explicitly.
+  if (browser_) {
+    BrowserDestroyed(browser_);
+  }
 }
 
 void SessionRestorationBrowserAgent::SetSessionID(
diff --git a/ios/chrome/browser/sessions/session_restoration_service_factory.mm b/ios/chrome/browser/sessions/session_restoration_service_factory.mm
index f2a442a..4b35876a 100644
--- a/ios/chrome/browser/sessions/session_restoration_service_factory.mm
+++ b/ios/chrome/browser/sessions/session_restoration_service_factory.mm
@@ -7,7 +7,9 @@
 #import "base/task/task_traits.h"
 #import "base/task/thread_pool.h"
 #import "components/keyed_service/ios/browser_state_dependency_manager.h"
+#import "ios/chrome/browser/sessions/legacy_session_restoration_service.h"
 #import "ios/chrome/browser/sessions/session_restoration_service_impl.h"
+#import "ios/chrome/browser/sessions/session_service_ios.h"
 #import "ios/chrome/browser/shared/model/browser_state/browser_state_otr_helper.h"
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/tabs/model/features.h"
@@ -40,7 +42,13 @@
 std::unique_ptr<KeyedService>
 SessionRestorationServiceFactory::BuildServiceInstanceFor(
     web::BrowserState* context) const {
-  DCHECK(web::features::UseSessionSerializationOptimizations());
+  // If the optimised session restoration format is not enabled, create a
+  // LegacySessionRestorationService instance which wraps the legacy API.
+  if (!web::features::UseSessionSerializationOptimizations()) {
+    return std::make_unique<LegacySessionRestorationService>(
+        IsPinnedTabsEnabled(), [SessionServiceIOS sharedService]);
+  }
+
   return std::make_unique<SessionRestorationServiceImpl>(
       base::Seconds(5), IsPinnedTabsEnabled(),
       ChromeBrowserState::FromBrowserState(context)->GetStatePath(),
diff --git a/ios/chrome/browser/sessions/session_restoration_service_factory_unittest.cc b/ios/chrome/browser/sessions/session_restoration_service_factory_unittest.cc
index 3f0d2815..ece69bbf 100644
--- a/ios/chrome/browser/sessions/session_restoration_service_factory_unittest.cc
+++ b/ios/chrome/browser/sessions/session_restoration_service_factory_unittest.cc
@@ -7,18 +7,45 @@
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h"
-#include "testing/platform_test.h"
+#include "testing/gtest/include/gtest/gtest.h"
 
 // To get access to web::features::kEnableSessionSerializationOptimizations.
 // TODO(crbug.com/1383087): remove once the feature is fully launched.
 #include "ios/web/common/features.h"
 
-class SessionRestorationServiceFactoryTest : public PlatformTest {
+namespace {
+
+struct SessionRestorationServiceFactoryTestParam {
+  const bool enable_session_serialization_optimization;
+};
+
+constexpr SessionRestorationServiceFactoryTestParam
+    kEnableSessionSerializationOptimization = {
+        .enable_session_serialization_optimization = true,
+};
+
+constexpr SessionRestorationServiceFactoryTestParam
+    kDisableSessionSerializationOptimization = {
+        .enable_session_serialization_optimization = false,
+};
+
+}  // namespace
+
+class SessionRestorationServiceFactoryTest
+    : public testing::TestWithParam<SessionRestorationServiceFactoryTestParam> {
  public:
   SessionRestorationServiceFactoryTest() {
-    scoped_feature_list_.InitAndEnableFeature(
-        web::features::kEnableSessionSerializationOptimizations);
+    scoped_feature_list_ = std::make_unique<base::test::ScopedFeatureList>();
+    const SessionRestorationServiceFactoryTestParam param = GetParam();
+    if (param.enable_session_serialization_optimization) {
+      scoped_feature_list_->InitAndEnableFeature(
+          web::features::kEnableSessionSerializationOptimizations);
+    } else {
+      scoped_feature_list_->InitAndDisableFeature(
+          web::features::kEnableSessionSerializationOptimizations);
+    }
 
+    task_environment_ = std::make_unique<base::test::TaskEnvironment>();
     browser_state_ = TestChromeBrowserState::Builder().Build();
   }
 
@@ -29,26 +56,32 @@
   }
 
  private:
-  base::test::ScopedFeatureList scoped_feature_list_;
-  base::test::TaskEnvironment task_environment_;
+  std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_;
+  std::unique_ptr<base::test::TaskEnvironment> task_environment_;
   std::unique_ptr<TestChromeBrowserState> browser_state_;
 };
 
+INSTANTIATE_TEST_SUITE_P(
+    SessionRestorationServiceFactoryTestWithFeatureSelection,
+    SessionRestorationServiceFactoryTest,
+    ::testing::Values(kEnableSessionSerializationOptimization,
+                      kDisableSessionSerializationOptimization));
+
 // Tests that the factory correctly instantiate a new service.
-TEST_F(SessionRestorationServiceFactoryTest, CreateInstance) {
+TEST_P(SessionRestorationServiceFactoryTest, CreateInstance) {
   EXPECT_TRUE(
       SessionRestorationServiceFactory::GetForBrowserState(browser_state()));
 }
 
 // Tests that the factory correctly instantiate a new service for off-the-record
 // BrowserState.
-TEST_F(SessionRestorationServiceFactoryTest, CreateOffTheRecordInstance) {
+TEST_P(SessionRestorationServiceFactoryTest, CreateOffTheRecordInstance) {
   EXPECT_TRUE(SessionRestorationServiceFactory::GetForBrowserState(
       otr_browser_state()));
 }
 
 // Tests that regular and off-the-record BrowserState uses distinct instances.
-TEST_F(SessionRestorationServiceFactoryTest, InstancesAreDistinct) {
+TEST_P(SessionRestorationServiceFactoryTest, InstancesAreDistinct) {
   EXPECT_NE(
       SessionRestorationServiceFactory::GetForBrowserState(browser_state()),
       SessionRestorationServiceFactory::GetForBrowserState(
diff --git a/ios/chrome/browser/shared/coordinator/scene/BUILD.gn b/ios/chrome/browser/shared/coordinator/scene/BUILD.gn
index b8b97f5..7f58e13c 100644
--- a/ios/chrome/browser/shared/coordinator/scene/BUILD.gn
+++ b/ios/chrome/browser/shared/coordinator/scene/BUILD.gn
@@ -91,11 +91,11 @@
     "//ios/chrome/browser/first_run",
     "//ios/chrome/browser/geolocation/model",
     "//ios/chrome/browser/infobars",
+    "//ios/chrome/browser/intents:user_activity_handler",
     "//ios/chrome/browser/mailto_handler",
     "//ios/chrome/browser/mailto_handler:mailto_handler_factory",
     "//ios/chrome/browser/main",
     "//ios/chrome/browser/ntp",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/passwords/model",
     "//ios/chrome/browser/passwords/model:password_checkup_utils",
     "//ios/chrome/browser/policy",
diff --git a/ios/chrome/browser/shared/coordinator/scene/DEPS b/ios/chrome/browser/shared/coordinator/scene/DEPS
index c3eb2092..a3b9309 100644
--- a/ios/chrome/browser/shared/coordinator/scene/DEPS
+++ b/ios/chrome/browser/shared/coordinator/scene/DEPS
@@ -6,6 +6,7 @@
   "+ios/chrome/browser/first_run",
   "+ios/chrome/browser/geolocation/model",
   "+ios/chrome/browser/infobars",
+  "+ios/chrome/browser/intents/user_activity_handler.h",
   "+ios/chrome/browser/mailto_handler",
   "+ios/chrome/browser/main",
   "+ios/chrome/browser/ntp",
diff --git a/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm b/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm
index a519b9b..d921db0 100644
--- a/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm
+++ b/ios/chrome/browser/shared/coordinator/scene/scene_controller.mm
@@ -37,7 +37,6 @@
 #import "ios/chrome/app/application_delegate/startup_information.h"
 #import "ios/chrome/app/application_delegate/url_opener.h"
 #import "ios/chrome/app/application_delegate/url_opener_params.h"
-#import "ios/chrome/app/application_delegate/user_activity_handler.h"
 #import "ios/chrome/app/application_mode.h"
 #import "ios/chrome/app/chrome_overlay_window.h"
 #import "ios/chrome/app/deferred_initialization_runner.h"
@@ -55,10 +54,10 @@
 #import "ios/chrome/browser/first_run/first_run.h"
 #import "ios/chrome/browser/geolocation/model/geolocation_logger.h"
 #import "ios/chrome/browser/infobars/infobar_manager_impl.h"
+#import "ios/chrome/browser/intents/user_activity_handler.h"
 #import "ios/chrome/browser/mailto_handler/mailto_handler_service.h"
 #import "ios/chrome/browser/mailto_handler/mailto_handler_service_factory.h"
 #import "ios/chrome/browser/main/browser_util.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h"
 #import "ios/chrome/browser/passwords/model/ios_chrome_password_check_manager.h"
 #import "ios/chrome/browser/passwords/model/ios_chrome_password_check_manager_factory.h"
diff --git a/ios/chrome/browser/shared/coordinator/scene/scene_util.mm b/ios/chrome/browser/shared/coordinator/scene/scene_util.mm
index 951a3de..d00070b 100644
--- a/ios/chrome/browser/shared/coordinator/scene/scene_util.mm
+++ b/ios/chrome/browser/shared/coordinator/scene/scene_util.mm
@@ -6,6 +6,7 @@
 
 #import <UIKit/UIKit.h>
 
+#import "base/check.h"
 #import "base/ios/ios_util.h"
 
 namespace {
diff --git a/ios/chrome/browser/shared/public/features/BUILD.gn b/ios/chrome/browser/shared/public/features/BUILD.gn
index 06e5b50..e61d1fe 100644
--- a/ios/chrome/browser/shared/public/features/BUILD.gn
+++ b/ios/chrome/browser/shared/public/features/BUILD.gn
@@ -7,7 +7,13 @@
     "features.h",
     "features.mm",
   ]
-  deps = [ "//ui/base" ]
+  deps = [
+    "//components/country_codes",
+    "//components/version_info:channel",
+    "//ios/chrome/app:background_mode_buildflags",
+    "//ios/chrome/common",
+    "//ui/base",
+  ]
   public_deps = [ "//base" ]
 }
 
diff --git a/ios/chrome/browser/shared/public/features/features.h b/ios/chrome/browser/shared/public/features/features.h
index d9278f34..7e368b6 100644
--- a/ios/chrome/browser/shared/public/features/features.h
+++ b/ios/chrome/browser/shared/public/features/features.h
@@ -5,10 +5,16 @@
 #ifndef IOS_CHROME_BROWSER_SHARED_PUBLIC_FEATURES_FEATURES_H_
 #define IOS_CHROME_BROWSER_SHARED_PUBLIC_FEATURES_FEATURES_H_
 
+#import <Foundation/Foundation.h>
+
 #include "Availability.h"
 #include "base/feature_list.h"
 #include "base/metrics/field_trial_params.h"
 
+namespace base {
+class TimeDelta;
+}  // namespace base
+
 // Feature flag to enable the Payments Bottom Sheet.
 BASE_DECLARE_FEATURE(kIOSPaymentsBottomSheet);
 
@@ -252,4 +258,335 @@
 // enabled.
 BASE_DECLARE_FEATURE(kEnableBatchUploadFromBookmarksManager);
 
+// Engagement criteria type for a feed refresh.
+enum class FeedRefreshEngagementCriteriaType {
+  // Any scroll or interaction.
+  kSimpleEngagement = 0,
+  // Meets minimum scroll criteria or any interaction.
+  kEngagement = 1,
+  // Meets good visit criteria.
+  kGoodVisit = 2,
+  kMaxValue = kGoodVisit,
+};
+
+// Feature flag to enable feed background refresh.
+// Use IsFeedBackgroundRefreshEnabled() instead of this constant directly.
+BASE_DECLARE_FEATURE(kEnableFeedBackgroundRefresh);
+
+// Feature flag to enable feed invisible foreground refresh. Check feature
+// params instead of using this constant.
+BASE_DECLARE_FEATURE(kEnableFeedInvisibleForegroundRefresh);
+
+// Feature flag to enable the Following feed in the NTP.
+// Use IsWebChannelsEnabled() instead of this constant directly.
+BASE_DECLARE_FEATURE(kEnableWebChannels);
+
+// Feature flag to enable Feed card menu promo feature, which displays a sign-in
+// promotion UI when signed out users click on personalization options within
+// the feed card menu.
+// Use IsFeedCardMenuSignInPromoEnabled() instead of this constant directly.
+BASE_DECLARE_FEATURE(kEnableFeedCardMenuSignInPromo);
+
+// Feature flag to disable the feed.
+BASE_DECLARE_FEATURE(kEnableFeedAblation);
+
+// Feature flag to enable feed experiment tagging.
+BASE_DECLARE_FEATURE(kEnableFeedExperimentTagging);
+
+// Feature flag to enable the Set Up List.
+BASE_DECLARE_FEATURE(kIOSSetUpList);
+
+// Feature flag to disable Discover-controlled foregrounding refreshes.
+BASE_DECLARE_FEATURE(kFeedDisableHotStartRefresh);
+
+// Feature flag to enable the Follow UI update.
+BASE_DECLARE_FEATURE(kEnableFollowUIUpdate);
+
+// Feature flag to enable the live sport card in the Discover feed.
+BASE_DECLARE_FEATURE(kDiscoverFeedSportCard);
+
+// Feature flag to enable the content notifications.
+BASE_DECLARE_FEATURE(kContentPushNotifications);
+
+// Feature flag to enable the Large Fakebox design changes.
+BASE_DECLARE_FEATURE(kIOSLargeFakebox);
+
+// Feature flag to enable hiding the feed and feed header depending on Search
+// Engine choice.
+BASE_DECLARE_FEATURE(kIOSHideFeedWithSearchChoice);
+
+// Feature param under `kEnableFeedBackgroundRefresh` to also enable background
+// refresh for the Following feed.
+extern const char kEnableFollowingFeedBackgroundRefresh[];
+
+// Feature param under `kEnableFeedBackgroundRefresh` to enable server driven
+// background refresh schedule.
+extern const char kEnableServerDrivenBackgroundRefreshSchedule[];
+
+// Feature param under `kEnableFeedBackgroundRefresh` to enable recurring
+// background refresh schedule.
+extern const char kEnableRecurringBackgroundRefreshSchedule[];
+
+// Feature param under `kEnableFeedBackgroundRefresh` for the max age that the
+// cache is still considered fresh.
+extern const char kMaxCacheAgeInSeconds[];
+
+// Feature param under `kEnableFeedBackgroundRefresh` for the background refresh
+// interval in seconds.
+extern const char kBackgroundRefreshIntervalInSeconds[];
+
+// Feature param under `kEnableFeedBackgroundRefresh` for the background refresh
+// max age in seconds. This value is compared against the age of the feed when
+// performing a background refresh. A zero value means the age check is ignored.
+extern const char kBackgroundRefreshMaxAgeInSeconds[];
+
+// Feature param under `kEnableFeedInvisibleForegroundRefresh` to enable refresh
+// following a Feed session.
+extern const char kEnableFeedSessionCloseForegroundRefresh[];
+
+// Feature param under `kEnableFeedInvisibleForegroundRefresh` to enable refresh
+// on app backgrounding.
+extern const char kEnableFeedAppCloseForegroundRefresh[];
+
+// Feature param under `kEnableFeedInvisibleForegroundRefresh` to enable refresh
+// soon after the app is backgrounded.
+extern const char kEnableFeedAppCloseBackgroundRefresh[];
+
+// Feature param under `kEnableFeedInvisibleForegroundRefresh` for the
+// engagement criteria type to refresh the feed.
+extern const char kFeedRefreshEngagementCriteriaType[];
+
+// Feature param under `kEnableFeedInvisibleForegroundRefresh` for the
+// background refresh interval in seconds.
+extern const char kAppCloseBackgroundRefreshIntervalInSeconds[];
+
+// Feature param under `kEnableFeedInvisibleForegroundRefresh` for the time
+// interval used to set the refresh timer.
+extern const char kFeedRefreshTimerTimeoutInSeconds[];
+
+// Feature param under `kEnableFeedInvisibleForegroundRefresh` for the refresh
+// threshold when the last refresh was seen.
+extern const char kFeedSeenRefreshThresholdInSeconds[];
+
+// Feature param under `kEnableFeedInvisibleForegroundRefresh` for the refresh
+// threshold when the last refresh was unseen.
+extern const char kFeedUnseenRefreshThresholdInSeconds[];
+
+// Feature param under `kEnableFeedInvisibleForegroundRefresh` to enable using
+// engagement as a signal to invalidate the cache when the app is foregrounded.
+// This can result in a visible refresh when the NTP is visible during
+// foregrounding, or invisible refresh when a non-NTP is shown during
+// foregrounding. The engagement signals may include a deep scroll or 4 views,
+// and no sooner than 5 minutes from the last refresh.
+extern const char
+    kEnableFeedUseInteractivityInvalidationForForegroundRefreshes[];
+
+// Feature param under `kIOSHideFeedWithSearchChoice` to only target the
+// feature at certain countries (i.e. only hide the feed when the device is
+// from those countries when the search engine is changed).
+extern const char kIOSHideFeedWithSearchChoiceTargeted[];
+
+// Whether the Following Feed is enabled on NTP.
+bool IsWebChannelsEnabled();
+
+// Whether the Discover service is created early, alongside the app creation.
+bool IsDiscoverFeedServiceCreatedEarly();
+
+// Whether feed background refresh is enabled and the capability was enabled at
+// startup.
+bool IsFeedBackgroundRefreshEnabled();
+
+// Whether feed background refresh capability is enabled. Returns the value in
+// NSUserDefaults set by
+// `SaveFeedBackgroundRefreshCapabilityEnabledForNextColdStart()`. This is used
+// because registering for background refreshes must happen early in app
+// initialization and FeatureList is not yet available. Enabling or disabling
+// background refresh features will always take effect after two cold starts
+// after the feature has been changed on the server (once for the Finch
+// configuration, and another for reading the stored value from NSUserDefaults).
+// This function always returns false if the `IOS_BACKGROUND_MODE_ENABLED`
+// buildflag is not defined.
+bool IsFeedBackgroundRefreshCapabilityEnabled();
+
+// Saves whether any background refresh experiment is enabled. This call
+// DCHECKs on the availability of `base::FeatureList`.
+void SaveFeedBackgroundRefreshCapabilityEnabledForNextColdStart();
+
+// Sets `timestamp` for key `NSUserDefaultsKey` to be displayed in Experimental
+// Settings in the Settings App. This is not available in stable.
+void SetFeedRefreshTimestamp(NSDate* timestamp, NSString* NSUserDefaultsKey);
+
+// Returns the override value from Experimental Settings in the Settings App. If
+// enabled, all values in Experimental Settings will override all corresponding
+// defaults.
+bool IsFeedOverrideDefaultsEnabled();
+
+// Returns true if the user should receive a local notification when a feed
+// background refresh is completed. Background refresh completion notifications
+// are only enabled by Experimental Settings.
+bool IsFeedBackgroundRefreshCompletedNotificationEnabled();
+
+// Whether the Following feed should also be refreshed in the background.
+bool IsFollowingFeedBackgroundRefreshEnabled();
+
+// Whether the background refresh schedule should be driven by server values.
+bool IsServerDrivenBackgroundRefreshScheduleEnabled();
+
+// Whether a new refresh should be scheduled after completion of a previous
+// background refresh.
+bool IsRecurringBackgroundRefreshScheduleEnabled();
+
+// Returns the max age that the cache is still considered fresh. In other words,
+// the feed freshness threshold.
+double GetFeedMaxCacheAgeInSeconds();
+
+// The earliest interval to refresh if server value is not used. This value is
+// an input into the DiscoverFeedService.
+double GetBackgroundRefreshIntervalInSeconds();
+
+// Returns the background refresh max age in seconds.
+double GetBackgroundRefreshMaxAgeInSeconds();
+
+// Whether feed can be refreshed while not visible.
+bool IsFeedInvisibleForegroundRefreshEnabled();
+
+// Whether feed is refreshed after the user ends a Feed session, but while the
+// app is still in the foreground (e.g., user switches tabs, user navigates away
+// from Feed in current tab).
+bool IsFeedSessionCloseForegroundRefreshEnabled();
+
+// Whether feed is refreshed at the moment the app is backgrounding. This is
+// different from background refresh.
+bool IsFeedAppCloseForegroundRefreshEnabled();
+
+// Whether feed is refreshed in the background soon after the app is
+// backgrounded, and the capability was enabled at startup.
+bool IsFeedAppCloseBackgroundRefreshEnabled();
+
+// Returns the engagement criteria type for a feed refresh.
+FeedRefreshEngagementCriteriaType GetFeedRefreshEngagementCriteriaType();
+
+// The earliest interval to refresh in the background after app enters the
+// background in app close background refresh.
+double GetAppCloseBackgroundRefreshIntervalInSeconds();
+
+// Returns the time interval used to set the session end timer.
+double GetFeedRefreshTimerTimeoutInSeconds();
+
+// Returns the refresh threshold (aka feed expiration) for a feed that has been
+// seen.
+double GetFeedSeenRefreshThresholdInSeconds();
+
+// Returns the refresh threshold (aka feed expiration) for an unseen feed.
+double GetFeedUnseenRefreshThresholdInSeconds();
+
+// Returns whether the feed hide with search choice feature should be targeted
+// only at devices from certain countries.
+bool IsIOSHideFeedWithSearchChoiceTargeted();
+
+// YES if user engagement is used as a signal to invalidate the cache when the
+// app is foregrounded. This can result in a visible refresh when the NTP is
+// visible during foregrounding, or invisible refresh when a non-NTP is shown
+// during foregrounding. The engagement signals may include a deep scroll or 4
+// views, and no sooner than 5 minutes from the last refresh.
+bool IsFeedUseInteractivityInvalidationForForegroundRefreshesEnabled();
+
+// YES if enabled Feed card menu promo.
+bool IsFeedCardMenuSignInPromoEnabled();
+
+// Whether the feed is disabled.
+bool IsFeedAblationEnabled();
+
+// Whether the feed experiment tagging is enabled.
+bool IsFeedExperimentTaggingEnabled();
+
+// Whether the Set Up List feature is enabled.
+bool IsIOSSetUpListEnabled();
+
+// Whether Discover-controlled foregrounding refreshes are disabled.
+bool IsFeedHotStartRefreshDisabled();
+
+// YES when Follow UI Update is enabled.
+bool IsFollowUIUpdateEnabled();
+
+// YES when the Content Push Notifications are enabled.
+bool IsContentPushNotificationsEnabled();
+
+// Returns true when the IOSLargeFakebox feature is enabled.
+bool IsIOSLargeFakeboxEnabled();
+
+// Returns true when the IOSHideFeedWithSearchChoice feature is enabled.
+bool IsIOSHideFeedWithSearchChoiceEnabled();
+
+// Feature for the Magic Stack.
+BASE_DECLARE_FEATURE(kMagicStack);
+
+// Feature that contains the feed in a module.
+BASE_DECLARE_FEATURE(kEnableFeedContainment);
+
+// Feature that enables tab resumption.
+BASE_DECLARE_FEATURE(kTabResumption);
+
+// A parameter to indicate whether the Most Visited Tiles should be in the Magic
+// Stack.
+extern const char kMagicStackMostVisitedModuleParam[];
+
+// A parameter representing how much to reduce the NTP top space margin. If it
+// is negative, it will increase the top space margin.
+extern const char kReducedSpaceParam[];
+
+// A parameter representing whether modules should not be added to the Magic
+// Stack if their content is irrelevant.
+extern const char kHideIrrelevantModulesParam[];
+
+// A parameter representing how many days before showing the compacted Set Up
+// List module in the Magic Stack.
+extern const char kSetUpListCompactedTimeThresholdDays[];
+
+// A parameter to indicate whether the native UI is enabled for the discover
+// feed.
+// TODO(crbug.com/1385512): Remove this.
+extern const char kDiscoverFeedIsNativeUIEnabled[];
+
+// Feature parameters for the tab resumption feature. If no parameter is set,
+// the default (most recent tab only) will be used.
+extern const char kTabResumptionParameterName[];
+extern const char kTabResumptionMostRecentTabOnlyParam[];
+extern const char kTabResumptionAllTabsParam[];
+extern const char kTabResumptionAllTabsOneDayThresholdParam[];
+
+// Whether the Magic Stack should be shown.
+bool IsMagicStackEnabled();
+
+// Whether the feed is contained in a Home module.
+bool IsFeedContainmentEnabled();
+
+// The minimum padding between the modules and the screen bounds on the Home
+// surface. Relies on `IsFeedContainmentEnabled()` being enabled.
+int HomeModuleMinimumPadding();
+
+// Whether the tab resumption feature is enabled.
+bool IsTabResumptionEnabled();
+
+// Whether the tab resumption feature is enabled for most recent tab only.
+bool IsTabResumptionEnabledForMostRecentTabOnly();
+
+// Convenience method for determining the tab resumption time threshold for
+// X-Devices tabs only.
+const base::TimeDelta TabResumptionForXDevicesTimeThreshold();
+
+// Whether the Most Visited Sites should be put into the Magic Stack.
+bool ShouldPutMostVisitedSitesInMagicStack();
+
+// How much the NTP top margin should be reduced by for the Magic Stack design.
+double ReducedNTPTopMarginSpaceForMagicStack();
+
+// Whether modules should not be added to the Magic Stack if their content is
+// irrelevant.
+bool ShouldHideIrrelevantModules();
+
+// How many days before showing the Compacted Set Up List module configuration
+// in the Magic Stack.
+int TimeUntilShowingCompactedSetUpList();
+
 #endif  // IOS_CHROME_BROWSER_SHARED_PUBLIC_FEATURES_FEATURES_H_
diff --git a/ios/chrome/browser/shared/public/features/features.mm b/ios/chrome/browser/shared/public/features/features.mm
index c01aa08..911bde1 100644
--- a/ios/chrome/browser/shared/public/features/features.mm
+++ b/ios/chrome/browser/shared/public/features/features.mm
@@ -4,8 +4,44 @@
 
 #import "ios/chrome/browser/shared/public/features/features.h"
 
+#import "base/containers/contains.h"
+#import "base/metrics/field_trial_params.h"
+#import "components/country_codes/country_codes.h"
+#import "components/version_info/channel.h"
+#import "ios/chrome/app/background_mode_buildflags.h"
+#import "ios/chrome/common/channel_info.h"
 #import "ui/base/device_form_factor.h"
 
+namespace {
+
+// Whether feed background refresh is enabled. This only checks if the feature
+// is enabled, not if the capability was enabled at startup.
+bool IsFeedBackgroundRefreshEnabledOnly() {
+  return base::FeatureList::IsEnabled(kEnableFeedBackgroundRefresh);
+}
+
+// Whether feed is refreshed in the background soon after the app is
+// backgrounded. This only checks if the feature is enabled, not if the
+// capability was enabled at startup.
+bool IsFeedAppCloseBackgroundRefreshEnabledOnly() {
+  return base::GetFieldTrialParamByFeatureAsBool(
+      kEnableFeedInvisibleForegroundRefresh,
+      kEnableFeedAppCloseBackgroundRefresh,
+      /*default=*/false);
+}
+
+// Returns the override value from the Foreground Refresh section of Feed
+// Refresh Settings in Experimental Settings in the Settings App.
+bool IsFeedOverrideForegroundDefaultsEnabled() {
+  if (GetChannel() == version_info::Channel::STABLE) {
+    return false;
+  }
+  return [[NSUserDefaults standardUserDefaults]
+      boolForKey:@"FeedOverrideForegroundDefaultsEnabled"];
+}
+
+}  // namespace
+
 BASE_FEATURE(kIOSPaymentsBottomSheet,
              "IOSPaymentsBottomSheet",
              base::FEATURE_DISABLED_BY_DEFAULT);
@@ -289,3 +325,440 @@
 BASE_FEATURE(kEnableBatchUploadFromBookmarksManager,
              "EnableBatchUploadFromBookmarksManager",
              base::FEATURE_DISABLED_BY_DEFAULT);
+
+BASE_FEATURE(kEnableWebChannels,
+             "EnableWebChannels",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
+BASE_FEATURE(kEnableFeedBackgroundRefresh,
+             "EnableFeedBackgroundRefresh",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
+BASE_FEATURE(kEnableFeedInvisibleForegroundRefresh,
+             "EnableFeedInvisibleForegroundRefresh",
+             base::FEATURE_ENABLED_BY_DEFAULT);
+
+BASE_FEATURE(kCreateDiscoverFeedServiceEarly,
+             "CreateDiscoverFeedServiceEarly",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
+BASE_FEATURE(kEnableFeedCardMenuSignInPromo,
+             "EnableFeedCardMenuSignInPromo",
+             base::FEATURE_ENABLED_BY_DEFAULT);
+
+BASE_FEATURE(kEnableFeedAblation,
+             "EnableFeedAblation",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
+BASE_FEATURE(kEnableFeedExperimentTagging,
+             "EnableFeedExperimentTagging",
+             base::FEATURE_ENABLED_BY_DEFAULT);
+
+BASE_FEATURE(kIOSSetUpList, "IOSSetUpList", base::FEATURE_ENABLED_BY_DEFAULT);
+
+BASE_FEATURE(kFeedDisableHotStartRefresh,
+             "FeedDisableHotStartRefresh",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
+BASE_FEATURE(kEnableFollowUIUpdate,
+             "EnableFollowUIUpdate",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
+BASE_FEATURE(kDiscoverFeedSportCard,
+             "DiscoverFeedSportCard",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
+BASE_FEATURE(kContentPushNotifications,
+             "ContentPushNotifications",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
+BASE_FEATURE(kIOSLargeFakebox,
+             "IOSLargeFakebox",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
+BASE_FEATURE(kIOSHideFeedWithSearchChoice,
+             "IOSHideFeedWithSearchChoice",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
+// Key for NSUserDefaults containing a bool indicating whether the next run
+// should enable feed background refresh capability. This is used because
+// registering for background refreshes must happen early in app initialization
+// and FeatureList is not yet available. Enabling or disabling background
+// refresh features will always take effect after two cold starts after the
+// feature has been changed on the server (once for the Finch configuration, and
+// another for reading the stored value from NSUserDefaults).
+NSString* const kEnableFeedBackgroundRefreshCapabilityForNextColdStart =
+    @"EnableFeedBackgroundRefreshCapabilityForNextColdStart";
+
+const char kEnableFollowingFeedBackgroundRefresh[] =
+    "EnableFollowingFeedBackgroundRefresh";
+const char kEnableServerDrivenBackgroundRefreshSchedule[] =
+    "EnableServerDrivenBackgroundRefreshSchedule";
+const char kEnableRecurringBackgroundRefreshSchedule[] =
+    "EnableRecurringBackgroundRefreshSchedule";
+const char kMaxCacheAgeInSeconds[] = "MaxCacheAgeInSeconds";
+const char kBackgroundRefreshIntervalInSeconds[] =
+    "BackgroundRefreshIntervalInSeconds";
+const char kBackgroundRefreshMaxAgeInSeconds[] =
+    "BackgroundRefreshMaxAgeInSeconds";
+const char kEnableFeedSessionCloseForegroundRefresh[] =
+    "EnableFeedSessionCloseForegroundRefresh";
+const char kEnableFeedAppCloseForegroundRefresh[] =
+    "EnableFeedAppCloseForegroundRefresh";
+const char kEnableFeedAppCloseBackgroundRefresh[] =
+    "EnableFeedAppCloseBackgroundRefresh";
+const char kFeedRefreshEngagementCriteriaType[] =
+    "FeedRefreshEngagementCriteriaType";
+const char kAppCloseBackgroundRefreshIntervalInSeconds[] =
+    "AppCloseBackgroundRefreshIntervalInSeconds";
+const char kFeedRefreshTimerTimeoutInSeconds[] =
+    "FeedRefreshTimerTimeoutInSeconds";
+const char kFeedSeenRefreshThresholdInSeconds[] =
+    "FeedSeenRefreshThresholdInSeconds";
+const char kFeedUnseenRefreshThresholdInSeconds[] =
+    "FeedUnseenRefreshThresholdInSeconds";
+const char kEnableFeedUseInteractivityInvalidationForForegroundRefreshes[] =
+    "EnableFeedUseInteractivityInvalidationForForegroundRefreshes";
+const char kIOSHideFeedWithSearchChoiceTargeted[] =
+    "IOSHideFeedWithSearchChoiceTargeted";
+
+bool IsWebChannelsEnabled() {
+  std::string launched_countries[6] = {"AU", "CA", "GB", "NZ", "US", "ZA"};
+  if (base::Contains(launched_countries,
+                     country_codes::GetCurrentCountryCode())) {
+    return true;
+  }
+  return base::FeatureList::IsEnabled(kEnableWebChannels);
+}
+
+bool IsDiscoverFeedServiceCreatedEarly() {
+  return base::FeatureList::IsEnabled(kCreateDiscoverFeedServiceEarly);
+}
+
+bool IsFeedBackgroundRefreshEnabled() {
+  return IsFeedBackgroundRefreshCapabilityEnabled() &&
+         IsFeedBackgroundRefreshEnabledOnly();
+}
+
+bool IsFeedBackgroundRefreshCapabilityEnabled() {
+#if !BUILDFLAG(IOS_BACKGROUND_MODE_ENABLED)
+  return false;
+#else
+  static bool feedBackgroundRefreshEnabled =
+      [[NSUserDefaults standardUserDefaults]
+          boolForKey:kEnableFeedBackgroundRefreshCapabilityForNextColdStart];
+  return feedBackgroundRefreshEnabled;
+#endif  // BUILDFLAG(IOS_BACKGROUND_MODE_ENABLED)
+}
+
+void SaveFeedBackgroundRefreshCapabilityEnabledForNextColdStart() {
+  DCHECK(base::FeatureList::GetInstance());
+  BOOL enabled = IsFeedBackgroundRefreshEnabledOnly() ||
+                 IsFeedAppCloseBackgroundRefreshEnabledOnly();
+  [[NSUserDefaults standardUserDefaults]
+      setBool:enabled
+       forKey:kEnableFeedBackgroundRefreshCapabilityForNextColdStart];
+}
+
+void SetFeedRefreshTimestamp(NSDate* timestamp, NSString* NSUserDefaultsKey) {
+  NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
+  dateFormatter.dateStyle = NSDateFormatterShortStyle;
+  dateFormatter.timeStyle = NSDateFormatterShortStyle;
+  dateFormatter.locale = [NSLocale autoupdatingCurrentLocale];
+  [[NSUserDefaults standardUserDefaults]
+      setObject:[dateFormatter stringFromDate:timestamp]
+         forKey:NSUserDefaultsKey];
+}
+
+bool IsFeedOverrideDefaultsEnabled() {
+  if (GetChannel() == version_info::Channel::STABLE) {
+    return false;
+  }
+  return [[NSUserDefaults standardUserDefaults]
+      boolForKey:@"FeedOverrideDefaultsEnabled"];
+}
+
+bool IsFeedBackgroundRefreshCompletedNotificationEnabled() {
+  if (GetChannel() == version_info::Channel::STABLE) {
+    return false;
+  }
+  return IsFeedBackgroundRefreshCapabilityEnabled() &&
+         [[NSUserDefaults standardUserDefaults]
+             boolForKey:@"FeedBackgroundRefreshNotificationEnabled"];
+}
+
+bool IsFollowingFeedBackgroundRefreshEnabled() {
+  if (IsFeedOverrideDefaultsEnabled()) {
+    return [[NSUserDefaults standardUserDefaults]
+        boolForKey:@"FollowingFeedBackgroundRefreshEnabled"];
+  }
+  return base::GetFieldTrialParamByFeatureAsBool(
+      kEnableFeedBackgroundRefresh, kEnableFollowingFeedBackgroundRefresh,
+      /*default=*/false);
+}
+
+bool IsServerDrivenBackgroundRefreshScheduleEnabled() {
+  if (IsFeedOverrideDefaultsEnabled()) {
+    return [[NSUserDefaults standardUserDefaults]
+        boolForKey:@"FeedServerDrivenBackgroundRefreshScheduleEnabled"];
+  }
+  return base::GetFieldTrialParamByFeatureAsBool(
+      kEnableFeedBackgroundRefresh,
+      kEnableServerDrivenBackgroundRefreshSchedule, /*default=*/false);
+}
+
+bool IsRecurringBackgroundRefreshScheduleEnabled() {
+  if (IsFeedOverrideDefaultsEnabled()) {
+    return [[NSUserDefaults standardUserDefaults]
+        boolForKey:@"FeedRecurringBackgroundRefreshScheduleEnabled"];
+  }
+  return base::GetFieldTrialParamByFeatureAsBool(
+      kEnableFeedBackgroundRefresh, kEnableRecurringBackgroundRefreshSchedule,
+      /*default=*/false);
+}
+
+double GetFeedMaxCacheAgeInSeconds() {
+  if (IsFeedOverrideDefaultsEnabled()) {
+    return [[NSUserDefaults standardUserDefaults]
+        doubleForKey:@"FeedMaxCacheAgeInSeconds"];
+  }
+  return base::GetFieldTrialParamByFeatureAsDouble(kEnableFeedBackgroundRefresh,
+                                                   kMaxCacheAgeInSeconds,
+                                                   /*default=*/8 * 60 * 60);
+}
+
+double GetBackgroundRefreshIntervalInSeconds() {
+  if (IsFeedOverrideDefaultsEnabled()) {
+    return [[NSUserDefaults standardUserDefaults]
+        doubleForKey:@"FeedBackgroundRefreshIntervalInSeconds"];
+  }
+  return base::GetFieldTrialParamByFeatureAsDouble(
+      kEnableFeedBackgroundRefresh, kBackgroundRefreshIntervalInSeconds,
+      /*default=*/60 * 60);
+}
+
+double GetBackgroundRefreshMaxAgeInSeconds() {
+  return base::GetFieldTrialParamByFeatureAsDouble(
+      kEnableFeedBackgroundRefresh, kBackgroundRefreshMaxAgeInSeconds,
+      /*default=*/0);
+}
+
+bool IsFeedInvisibleForegroundRefreshEnabled() {
+  return base::FeatureList::IsEnabled(kEnableFeedInvisibleForegroundRefresh);
+}
+
+bool IsFeedSessionCloseForegroundRefreshEnabled() {
+  return base::GetFieldTrialParamByFeatureAsBool(
+      kEnableFeedInvisibleForegroundRefresh,
+      kEnableFeedSessionCloseForegroundRefresh,
+      /*default=*/false);
+}
+
+bool IsFeedAppCloseForegroundRefreshEnabled() {
+  return base::GetFieldTrialParamByFeatureAsBool(
+      kEnableFeedInvisibleForegroundRefresh,
+      kEnableFeedAppCloseForegroundRefresh,
+      /*default=*/true);
+}
+
+bool IsFeedAppCloseBackgroundRefreshEnabled() {
+  return IsFeedBackgroundRefreshCapabilityEnabled() &&
+         IsFeedAppCloseBackgroundRefreshEnabledOnly();
+}
+
+FeedRefreshEngagementCriteriaType GetFeedRefreshEngagementCriteriaType() {
+  return (FeedRefreshEngagementCriteriaType)
+      base::GetFieldTrialParamByFeatureAsInt(
+          kEnableFeedInvisibleForegroundRefresh,
+          kFeedRefreshEngagementCriteriaType,
+          /*default_value=*/
+          (int)FeedRefreshEngagementCriteriaType::kSimpleEngagement);
+}
+
+double GetAppCloseBackgroundRefreshIntervalInSeconds() {
+  double override_value = [[NSUserDefaults standardUserDefaults]
+      doubleForKey:@"AppCloseBackgroundRefreshIntervalInSeconds"];
+  if (override_value > 0.0) {
+    return override_value;
+  }
+  return base::GetFieldTrialParamByFeatureAsDouble(
+      kEnableFeedInvisibleForegroundRefresh,
+      kAppCloseBackgroundRefreshIntervalInSeconds,
+      /*default=*/base::Minutes(5).InSecondsF());
+}
+
+double GetFeedRefreshTimerTimeoutInSeconds() {
+  double override_value = [[NSUserDefaults standardUserDefaults]
+      doubleForKey:@"FeedRefreshTimerTimeoutInSeconds"];
+  if (override_value > 0.0) {
+    return override_value;
+  }
+  return base::GetFieldTrialParamByFeatureAsDouble(
+      kEnableFeedInvisibleForegroundRefresh, kFeedRefreshTimerTimeoutInSeconds,
+      /*default=*/base::Minutes(5).InSecondsF());
+}
+
+double GetFeedSeenRefreshThresholdInSeconds() {
+  double override_value = [[NSUserDefaults standardUserDefaults]
+      doubleForKey:@"FeedSeenRefreshThresholdInSeconds"];
+  if (override_value > 0.0) {
+    return override_value;
+  }
+  return base::GetFieldTrialParamByFeatureAsDouble(
+      kEnableFeedInvisibleForegroundRefresh, kFeedSeenRefreshThresholdInSeconds,
+      /*default=*/base::Hours(1).InSecondsF());
+}
+
+double GetFeedUnseenRefreshThresholdInSeconds() {
+  double override_value = [[NSUserDefaults standardUserDefaults]
+      doubleForKey:@"FeedUnseenRefreshThresholdInSeconds"];
+  if (override_value > 0.0) {
+    return override_value;
+  }
+  return base::GetFieldTrialParamByFeatureAsDouble(
+      kEnableFeedInvisibleForegroundRefresh,
+      kFeedUnseenRefreshThresholdInSeconds,
+      /*default=*/base::Hours(6).InSecondsF());
+}
+
+bool IsFeedUseInteractivityInvalidationForForegroundRefreshesEnabled() {
+  if (IsFeedOverrideForegroundDefaultsEnabled()) {
+    return [[NSUserDefaults standardUserDefaults]
+        doubleForKey:
+            @"FeedUseInteractivityInvalidationForForegroundRefreshesEnabled"];
+  }
+  return base::GetFieldTrialParamByFeatureAsBool(
+      kEnableFeedInvisibleForegroundRefresh,
+      kEnableFeedUseInteractivityInvalidationForForegroundRefreshes,
+      /*default=*/false);
+}
+
+bool IsIOSHideFeedWithSearchChoiceTargeted() {
+  return base::GetFieldTrialParamByFeatureAsBool(
+      kIOSHideFeedWithSearchChoice, kIOSHideFeedWithSearchChoiceTargeted,
+      /*default=*/false);
+}
+
+bool IsFeedCardMenuSignInPromoEnabled() {
+  return base::FeatureList::IsEnabled(kEnableFeedCardMenuSignInPromo);
+}
+
+bool IsFeedAblationEnabled() {
+  return base::FeatureList::IsEnabled(kEnableFeedAblation);
+}
+
+bool IsFeedExperimentTaggingEnabled() {
+  return base::FeatureList::IsEnabled(kEnableFeedExperimentTagging);
+}
+
+bool IsIOSSetUpListEnabled() {
+  return base::FeatureList::IsEnabled(kIOSSetUpList);
+}
+
+bool IsFeedHotStartRefreshDisabled() {
+  return base::FeatureList::IsEnabled(kFeedDisableHotStartRefresh);
+}
+
+bool IsFollowUIUpdateEnabled() {
+  return base::FeatureList::IsEnabled(kEnableFollowUIUpdate);
+}
+
+bool IsContentPushNotificationsEnabled() {
+  return base::FeatureList::IsEnabled(kContentPushNotifications);
+}
+
+bool IsIOSLargeFakeboxEnabled() {
+  return base::FeatureList::IsEnabled(kIOSLargeFakebox);
+}
+
+bool IsIOSHideFeedWithSearchChoiceEnabled() {
+  return base::FeatureList::IsEnabled(kIOSHideFeedWithSearchChoice);
+}
+
+// Feature disabled by default.
+BASE_FEATURE(kMagicStack, "MagicStack", base::FEATURE_DISABLED_BY_DEFAULT);
+
+BASE_FEATURE(kEnableFeedContainment,
+             "EnableFeedContainment",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
+BASE_FEATURE(kTabResumption,
+             "TabResumption",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
+const char kMagicStackMostVisitedModuleParam[] = "MagicStackMostVisitedModule";
+
+const char kReducedSpaceParam[] = "ReducedNTPTopSpace";
+
+const char kHideIrrelevantModulesParam[] = "HideIrrelevantModules";
+
+const char kSetUpListCompactedTimeThresholdDays[] =
+    "SetUpListCompactedTimeThresholdDays";
+
+const char kHomeModuleMinimumPadding[] = "HomeModuleMinimumPadding";
+
+// A parameter to indicate whether the native UI is enabled for the discover
+// feed.
+const char kDiscoverFeedIsNativeUIEnabled[] = "DiscoverFeedIsNativeUIEnabled";
+
+const char kTabResumptionParameterName[] = "variant";
+const char kTabResumptionMostRecentTabOnlyParam[] =
+    "tab-resumption-recent-tab-only";
+const char kTabResumptionAllTabsParam[] = "tab-resumption-all-tabs";
+const char kTabResumptionAllTabsOneDayThresholdParam[] =
+    "tab-resumption-all-tabs-one-day-threshold";
+
+bool IsMagicStackEnabled() {
+  return base::FeatureList::IsEnabled(kMagicStack);
+}
+
+bool IsFeedContainmentEnabled() {
+  return base::FeatureList::IsEnabled(kEnableFeedContainment);
+}
+
+int HomeModuleMinimumPadding() {
+  return base::GetFieldTrialParamByFeatureAsInt(kEnableFeedContainment,
+                                                kHomeModuleMinimumPadding, 30);
+}
+
+bool IsTabResumptionEnabled() {
+  return IsMagicStackEnabled() && base::FeatureList::IsEnabled(kTabResumption);
+}
+
+bool IsTabResumptionEnabledForMostRecentTabOnly() {
+  CHECK(IsTabResumptionEnabled());
+  std::string feature_param = base::GetFieldTrialParamValueByFeature(
+      kTabResumption, kTabResumptionParameterName);
+  return feature_param == kTabResumptionMostRecentTabOnlyParam;
+}
+
+const base::TimeDelta TabResumptionForXDevicesTimeThreshold() {
+  CHECK(!IsTabResumptionEnabledForMostRecentTabOnly());
+
+  std::string feature_param = base::GetFieldTrialParamValueByFeature(
+      kTabResumption, kTabResumptionParameterName);
+  if (feature_param == kTabResumptionAllTabsOneDayThresholdParam) {
+    return base::Days(1);
+  }
+  return base::Hours(12);
+}
+
+bool ShouldPutMostVisitedSitesInMagicStack() {
+  return base::GetFieldTrialParamByFeatureAsBool(
+      kMagicStack, kMagicStackMostVisitedModuleParam, false);
+}
+
+double ReducedNTPTopMarginSpaceForMagicStack() {
+  return base::GetFieldTrialParamByFeatureAsDouble(kMagicStack,
+                                                   kReducedSpaceParam, 0);
+}
+
+bool ShouldHideIrrelevantModules() {
+  return base::GetFieldTrialParamByFeatureAsBool(
+      kMagicStack, kHideIrrelevantModulesParam, false);
+}
+
+int TimeUntilShowingCompactedSetUpList() {
+  return base::GetFieldTrialParamByFeatureAsInt(
+      kMagicStack, kSetUpListCompactedTimeThresholdDays, 3);
+}
diff --git a/ios/chrome/browser/signin/authentication_service.mm b/ios/chrome/browser/signin/authentication_service.mm
index b774bf7a..557296b1 100644
--- a/ios/chrome/browser/signin/authentication_service.mm
+++ b/ios/chrome/browser/signin/authentication_service.mm
@@ -682,8 +682,12 @@
     AccountInfo extended_account_info =
         identity_manager_->FindExtendedAccountInfoByAccountId(
             account_info.account_id);
+    syncer::SyncUserSettings* user_settings = sync_service_->GetUserSettings();
+    bool history_sync_enabled = user_settings->GetSelectedTypes().HasAll(
+        {syncer::UserSelectableType::kHistory,
+         syncer::UserSelectableType::kTabs});
     StorePreRestoreIdentity(GetApplicationContext()->GetLocalState(),
-                            extended_account_info);
+                            extended_account_info, history_sync_enabled);
   }
 
   // Sign the user out.
diff --git a/ios/chrome/browser/signin/ios_chrome_signin_client.h b/ios/chrome/browser/signin/ios_chrome_signin_client.h
index f8ba4ca..22c763a8 100644
--- a/ios/chrome/browser/signin/ios_chrome_signin_client.h
+++ b/ios/chrome/browser/signin/ios_chrome_signin_client.h
@@ -52,6 +52,10 @@
   bool AreNetworkCallsDelayed() override;
   void DelayNetworkCall(base::OnceClosure callback) override;
   version_info::Channel GetClientChannel() override;
+  void OnPrimaryAccountChangedWithEventSource(
+      signin::PrimaryAccountChangeEvent event_details,
+      absl::variant<signin_metrics::AccessPoint, signin_metrics::ProfileSignout>
+          event_source) override;
 
  private:
   // Helper to delay callbacks until connection becomes online again.
diff --git a/ios/chrome/browser/signin/ios_chrome_signin_client.mm b/ios/chrome/browser/signin/ios_chrome_signin_client.mm
index 05e458b..74f2908 100644
--- a/ios/chrome/browser/signin/ios_chrome_signin_client.mm
+++ b/ios/chrome/browser/signin/ios_chrome_signin_client.mm
@@ -8,6 +8,7 @@
 #import "components/metrics/metrics_service.h"
 #import "components/signin/core/browser/cookie_settings_util.h"
 #import "components/signin/ios/browser/wait_for_network_callback_helper_ios.h"
+#import "components/signin/public/identity_manager/primary_account_change_event.h"
 #import "ios/chrome/browser/shared/model/application_context/application_context.h"
 #import "ios/chrome/browser/shared/model/browser_state/browser_state_info_cache.h"
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
@@ -85,3 +86,8 @@
 version_info::Channel IOSChromeSigninClient::GetClientChannel() {
   return GetChannel();
 }
+
+void IOSChromeSigninClient::OnPrimaryAccountChangedWithEventSource(
+    signin::PrimaryAccountChangeEvent event_details,
+    absl::variant<signin_metrics::AccessPoint, signin_metrics::ProfileSignout>
+        event_source) {}
diff --git a/ios/chrome/browser/signin/signin_util.h b/ios/chrome/browser/signin/signin_util.h
index d539e76..828fcfd 100644
--- a/ios/chrome/browser/signin/signin_util.h
+++ b/ios/chrome/browser/signin/signin_util.h
@@ -36,9 +36,11 @@
 // The value is cached. The result is cached for later calls.
 signin::Tribool IsFirstSessionAfterDeviceRestore();
 
-// Stores a user's account info in memory, when we detect that it was
-// forgotten during a device restore.
-void StorePreRestoreIdentity(PrefService* local_state, AccountInfo account);
+// Stores a user's account info and if history sync was enabled or not, when we
+// detect that it was forgotten during a device restore.
+void StorePreRestoreIdentity(PrefService* local_state,
+                             AccountInfo account,
+                             bool history_sync_enabled);
 
 // Clears the identity that was signed-in before the restore.
 void ClearPreRestoreIdentity(PrefService* local_state);
@@ -47,4 +49,7 @@
 // not signed-in.
 absl::optional<AccountInfo> GetPreRestoreIdentity(PrefService* local_state);
 
+// Returns whether history sync was enabled before the restore.
+bool GetPreRestoreHistorySyncEnabled(PrefService* local_state);
+
 #endif  // IOS_CHROME_BROWSER_SIGNIN_SIGNIN_UTIL_H_
diff --git a/ios/chrome/browser/signin/signin_util.mm b/ios/chrome/browser/signin/signin_util.mm
index 1e00e96..3cfab903 100644
--- a/ios/chrome/browser/signin/signin_util.mm
+++ b/ios/chrome/browser/signin/signin_util.mm
@@ -27,6 +27,7 @@
 const char kAccountInfoKeyFullName[] = "full_name";
 const char kAccountInfoKeyGivenName[] = "given_name";
 const char kAccountInfoKeyPictureUrl[] = "picture_url";
+const char kHistorySyncEnabled[] = "history_sync_enabled";
 
 // Copies a string value from a dictionary if the given key is present.
 void CopyStringFromDict(std::string& to,
@@ -102,7 +103,9 @@
   return is_first_session_after_device_restore;
 }
 
-void StorePreRestoreIdentity(PrefService* local_state, AccountInfo account) {
+void StorePreRestoreIdentity(PrefService* local_state,
+                             AccountInfo account,
+                             bool history_sync_enabled) {
   ScopedDictPrefUpdate update(local_state, prefs::kIosPreRestoreAccountInfo);
   update->Set(kAccountInfoKeyAccountId, account.account_id.ToString());
   update->Set(kAccountInfoKeyGaia, account.gaia);
@@ -110,6 +113,7 @@
   update->Set(kAccountInfoKeyFullName, account.full_name);
   update->Set(kAccountInfoKeyGivenName, account.given_name);
   update->Set(kAccountInfoKeyPictureUrl, account.picture_url);
+  update->Set(kHistorySyncEnabled, history_sync_enabled);
 }
 
 void ClearPreRestoreIdentity(PrefService* local_state) {
@@ -124,3 +128,14 @@
   }
   return DictToAccountInfo(dict);
 }
+
+bool GetPreRestoreHistorySyncEnabled(PrefService* local_state) {
+  const base::Value::Dict& dict =
+      local_state->GetDict(prefs::kIosPreRestoreAccountInfo);
+  if (dict.empty()) {
+    return false;
+  }
+  absl::optional<bool> history_sync_enabled =
+      dict.FindBool(kHistorySyncEnabled);
+  return history_sync_enabled.value_or(false);
+}
diff --git a/ios/chrome/browser/signin/signin_util_unittest.mm b/ios/chrome/browser/signin/signin_util_unittest.mm
index 5054701..1eb3d9a 100644
--- a/ios/chrome/browser/signin/signin_util_unittest.mm
+++ b/ios/chrome/browser/signin/signin_util_unittest.mm
@@ -52,7 +52,8 @@
   EXPECT_FALSE(GetPreRestoreIdentity(&local_state_).has_value());
 
   AccountInfo account = FakeAccountFull();
-  StorePreRestoreIdentity(&local_state_, account);
+  StorePreRestoreIdentity(&local_state_, account,
+                          /*history_sync_enabled=*/false);
 
   // Verify that the retrieved account info is the same as what was stored.
   auto retrieved_account = GetPreRestoreIdentity(&local_state_);
@@ -65,7 +66,8 @@
   EXPECT_FALSE(GetPreRestoreIdentity(&local_state_).has_value());
 
   AccountInfo account = FakeAccountMinimal();
-  StorePreRestoreIdentity(&local_state_, account);
+  StorePreRestoreIdentity(&local_state_, account,
+                          /*history_sync_enabled=*/false);
 
   // Verify that the retrieved account info is the same as what was stored.
   auto retrieved_account = GetPreRestoreIdentity(&local_state_);
@@ -74,9 +76,12 @@
 }
 
 TEST_F(SigninUtilTest, ClearPreRestoreIdentity) {
-  StorePreRestoreIdentity(&local_state_, FakeAccountFull());
+  StorePreRestoreIdentity(&local_state_, FakeAccountFull(),
+                          /*history_sync_enabled=*/true);
   EXPECT_TRUE(GetPreRestoreIdentity(&local_state_).has_value());
+  EXPECT_TRUE(GetPreRestoreHistorySyncEnabled(&local_state_));
 
   ClearPreRestoreIdentity(&local_state_);
   EXPECT_FALSE(GetPreRestoreIdentity(&local_state_).has_value());
+  EXPECT_FALSE(GetPreRestoreHistorySyncEnabled(&local_state_));
 }
diff --git a/ios/chrome/browser/supervised_user/model/BUILD.gn b/ios/chrome/browser/supervised_user/model/BUILD.gn
index d70bced..74e5f24 100644
--- a/ios/chrome/browser/supervised_user/model/BUILD.gn
+++ b/ios/chrome/browser/supervised_user/model/BUILD.gn
@@ -82,6 +82,7 @@
     "//components/signin/public/identity_manager:test_support",
     "//components/supervised_user/core/browser",
     "//components/supervised_user/core/browser:list_family_members_service",
+    "//components/supervised_user/core/browser:supervised_user_preferences",
     "//components/supervised_user/core/common",
     "//components/supervised_user/test_support",
     "//components/sync_preferences",
diff --git a/ios/chrome/browser/supervised_user/model/supervised_user_url_filter_tab_helper_unittest.mm b/ios/chrome/browser/supervised_user/model/supervised_user_url_filter_tab_helper_unittest.mm
index d0d568c1..f6e15866 100644
--- a/ios/chrome/browser/supervised_user/model/supervised_user_url_filter_tab_helper_unittest.mm
+++ b/ios/chrome/browser/supervised_user/model/supervised_user_url_filter_tab_helper_unittest.mm
@@ -11,6 +11,7 @@
 #import "components/signin/public/identity_manager/account_capabilities_test_mutator.h"
 #import "components/signin/public/identity_manager/identity_manager.h"
 #import "components/signin/public/identity_manager/identity_test_utils.h"
+#import "components/supervised_user/core/browser/supervised_user_preferences.h"
 #import "components/supervised_user/core/browser/supervised_user_service.h"
 #import "components/supervised_user/core/browser/supervised_user_settings_service.h"
 #import "components/supervised_user/core/common/features.h"
@@ -95,8 +96,9 @@
             chrome_browser_state_.get());
     supervised_user_service->Init();
 
-    EXPECT_EQ(supervised_user_service->IsSubjectToParentalControls(),
-              is_subject_to_parental_controls);
+    EXPECT_EQ(
+        supervised_user::IsChildAccount(*chrome_browser_state_->GetPrefs()),
+        is_subject_to_parental_controls);
   }
 
   // Calls `ShouldAllowRequest` for a request with the given `url_string`.
diff --git a/ios/chrome/browser/tabs/model/BUILD.gn b/ios/chrome/browser/tabs/model/BUILD.gn
index 24d4e83..164cd045 100644
--- a/ios/chrome/browser/tabs/model/BUILD.gn
+++ b/ios/chrome/browser/tabs/model/BUILD.gn
@@ -83,7 +83,6 @@
     "//ios/chrome/browser/main",
     "//ios/chrome/browser/metrics",
     "//ios/chrome/browser/ntp",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/optimization_guide",
     "//ios/chrome/browser/overscroll_actions/model",
     "//ios/chrome/browser/passwords/model",
diff --git a/ios/chrome/browser/tabs/model/tab_helper_util.mm b/ios/chrome/browser/tabs/model/tab_helper_util.mm
index 258a094..f8da5ab 100644
--- a/ios/chrome/browser/tabs/model/tab_helper_util.mm
+++ b/ios/chrome/browser/tabs/model/tab_helper_util.mm
@@ -57,7 +57,6 @@
 #import "ios/chrome/browser/lens/lens_tab_helper.h"
 #import "ios/chrome/browser/link_to_text/model/link_to_text_tab_helper.h"
 #import "ios/chrome/browser/metrics/pageload_foreground_duration_tab_helper.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h"
 #import "ios/chrome/browser/optimization_guide/optimization_guide_tab_helper.h"
 #import "ios/chrome/browser/optimization_guide/optimization_guide_validation_tab_helper.h"
diff --git a/ios/chrome/browser/tabs/model/tab_pickup/BUILD.gn b/ios/chrome/browser/tabs/model/tab_pickup/BUILD.gn
index 9e91dac..7e57f6b 100644
--- a/ios/chrome/browser/tabs/model/tab_pickup/BUILD.gn
+++ b/ios/chrome/browser/tabs/model/tab_pickup/BUILD.gn
@@ -22,6 +22,7 @@
     "//ios/chrome/browser/shared/model/browser_state",
     "//ios/chrome/browser/shared/model/prefs:pref_names",
     "//ios/chrome/browser/shared/model/web_state_list",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/sync/model",
     "//ios/chrome/browser/synced_sessions/model",
     "//ios/chrome/browser/tabs/model:tab_sync_util",
diff --git a/ios/chrome/browser/tabs/model/tab_pickup/DEPS b/ios/chrome/browser/tabs/model/tab_pickup/DEPS
index 1e0bf08..4480c4d 100644
--- a/ios/chrome/browser/tabs/model/tab_pickup/DEPS
+++ b/ios/chrome/browser/tabs/model/tab_pickup/DEPS
@@ -3,5 +3,4 @@
   "+ios/chrome/browser/synced_sessions/model",
   "+ios/chrome/browser/favicon",
   "+ios/chrome/browser/metrics",
-  "+ios/chrome/browser/ntp/home/features.h",
 ]
diff --git a/ios/chrome/browser/tabs/model/tab_pickup/tab_pickup_browser_agent.mm b/ios/chrome/browser/tabs/model/tab_pickup/tab_pickup_browser_agent.mm
index e77a2a0..dd3ad996 100644
--- a/ios/chrome/browser/tabs/model/tab_pickup/tab_pickup_browser_agent.mm
+++ b/ios/chrome/browser/tabs/model/tab_pickup/tab_pickup_browser_agent.mm
@@ -10,12 +10,12 @@
 #import "components/sync_sessions/session_sync_service.h"
 #import "ios/chrome/browser/infobars/infobar_ios.h"
 #import "ios/chrome/browser/infobars/infobar_manager_impl.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/ntp/new_tab_page_util.h"
 #import "ios/chrome/browser/shared/model/application_context/application_context.h"
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/shared/model/prefs/pref_names.h"
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/sync/model/session_sync_service_factory.h"
 #import "ios/chrome/browser/synced_sessions/model/distant_session.h"
 #import "ios/chrome/browser/synced_sessions/model/distant_tab.h"
diff --git a/ios/chrome/browser/ui/authentication/cells/signin_promo_view.mm b/ios/chrome/browser/ui/authentication/cells/signin_promo_view.mm
index 3dc26e9..bf1732b 100644
--- a/ios/chrome/browser/ui/authentication/cells/signin_promo_view.mm
+++ b/ios/chrome/browser/ui/authentication/cells/signin_promo_view.mm
@@ -10,7 +10,6 @@
 #import "base/notreached.h"
 #import "build/branding_buildflags.h"
 #import "components/signin/public/base/signin_metrics.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
 #import "ios/chrome/browser/ui/authentication/cells/signin_promo_view_constants.h"
diff --git a/ios/chrome/browser/ui/authentication/signin/BUILD.gn b/ios/chrome/browser/ui/authentication/signin/BUILD.gn
index bf194a4..ac6a042c 100644
--- a/ios/chrome/browser/ui/authentication/signin/BUILD.gn
+++ b/ios/chrome/browser/ui/authentication/signin/BUILD.gn
@@ -158,6 +158,7 @@
     "//ios/chrome/browser/policy:eg_test_support+eg2",
     "//ios/chrome/browser/policy:policy_util",
     "//ios/chrome/browser/shared/model/prefs:pref_names",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/shared/ui/elements:constants",
     "//ios/chrome/browser/signin:capabilities_types",
     "//ios/chrome/browser/signin:fake_system_identity",
diff --git a/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/BUILD.gn b/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/BUILD.gn
index 8aed04e..8e4ef716 100644
--- a/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/BUILD.gn
+++ b/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/BUILD.gn
@@ -87,6 +87,7 @@
     "//components/sync/base:features",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/ntp/home:features",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/signin:fake_system_identity",
     "//ios/chrome/browser/ui/authentication:eg_test_support+eg2",
     "//ios/chrome/browser/ui/authentication/signin/advanced_settings_signin:constants",
diff --git a/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_egtest.mm b/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_egtest.mm
index 75feab29..b0f821b 100644
--- a/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_egtest.mm
+++ b/ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_egtest.mm
@@ -11,7 +11,7 @@
 #import "components/bookmarks/common/storage_type.h"
 #import "components/strings/grit/components_strings.h"
 #import "components/sync/base/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/signin/fake_system_identity.h"
 #import "ios/chrome/browser/ui/authentication/signin/advanced_settings_signin/advanced_settings_signin_constants.h"
 #import "ios/chrome/browser/ui/authentication/signin_earl_grey.h"
diff --git a/ios/chrome/browser/ui/authentication/signin/signin_coordinator_egtest.mm b/ios/chrome/browser/ui/authentication/signin/signin_coordinator_egtest.mm
index d8fc4ca..4a51d870 100644
--- a/ios/chrome/browser/ui/authentication/signin/signin_coordinator_egtest.mm
+++ b/ios/chrome/browser/ui/authentication/signin/signin_coordinator_egtest.mm
@@ -16,10 +16,10 @@
 #import "components/sync/base/features.h"
 #import "components/sync/base/user_selectable_type.h"
 #import "ios/chrome/browser/metrics/metrics_app_interface.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/policy/policy_earl_grey_utils.h"
 #import "ios/chrome/browser/policy/policy_util.h"
 #import "ios/chrome/browser/shared/model/prefs/pref_names.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/elements/elements_constants.h"
 #import "ios/chrome/browser/signin/capabilities_types.h"
 #import "ios/chrome/browser/signin/fake_system_identity.h"
diff --git a/ios/chrome/browser/ui/autofill/bottom_sheet/payments_suggestion_bottom_sheet_mediator.mm b/ios/chrome/browser/ui/autofill/bottom_sheet/payments_suggestion_bottom_sheet_mediator.mm
index 25006f03..7a838a2 100644
--- a/ios/chrome/browser/ui/autofill/bottom_sheet/payments_suggestion_bottom_sheet_mediator.mm
+++ b/ios/chrome/browser/ui/autofill/bottom_sheet/payments_suggestion_bottom_sheet_mediator.mm
@@ -425,12 +425,14 @@
   }
 
   // Otherwise, try to get the default card icon
-  std::string icon = creditCard->CardIconStringForAutofillSuggestion();
-  return icon.empty() ? nil
-                      : ui::ResourceBundle::GetSharedInstance()
-                            .GetNativeImageNamed(
-                                autofill::CreditCard::IconResourceId(icon))
-                            .ToUIImage();
+  autofill::Suggestion::Icon icon =
+      creditCard->CardIconStringForAutofillSuggestion();
+  return icon == autofill::Suggestion::Icon::kNoIcon
+             ? nil
+             : ui::ResourceBundle::GetSharedInstance()
+                   .GetNativeImageNamed(
+                       autofill::CreditCard::IconResourceId(icon))
+                   .ToUIImage();
 }
 
 @end
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/fallback_view_controller.mm b/ios/chrome/browser/ui/autofill/manual_fill/fallback_view_controller.mm
index e3247cab..3e6e3c90 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/fallback_view_controller.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/fallback_view_controller.mm
@@ -4,6 +4,7 @@
 
 #import "ios/chrome/browser/ui/autofill/manual_fill/fallback_view_controller.h"
 
+#import "base/check.h"
 #import "base/ios/ios_util.h"
 #import "ios/chrome/browser/shared/ui/table_view/legacy_chrome_table_view_styler.h"
 #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
diff --git a/ios/chrome/browser/ui/browser_view/BUILD.gn b/ios/chrome/browser/ui/browser_view/BUILD.gn
index 552aff5..4eade985 100644
--- a/ios/chrome/browser/ui/browser_view/BUILD.gn
+++ b/ios/chrome/browser/ui/browser_view/BUILD.gn
@@ -78,7 +78,6 @@
     "//ios/chrome/browser/metrics:metrics_internal",
     "//ios/chrome/browser/net",
     "//ios/chrome/browser/ntp",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/ntp:util",
     "//ios/chrome/browser/ntp/home:features",
     "//ios/chrome/browser/overlays",
@@ -390,7 +389,6 @@
     "//base/test:test_support",
     "//components/strings",
     "//ios/chrome/app/strings",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/ntp/home:features",
     "//ios/chrome/browser/shared/model/prefs:pref_names",
     "//ios/chrome/browser/shared/public/features",
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
index 09d8ea2c..72315f5 100644
--- a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
@@ -44,7 +44,6 @@
 #import "ios/chrome/browser/infobars/infobar_manager_impl.h"
 #import "ios/chrome/browser/intents/intents_donation_helper.h"
 #import "ios/chrome/browser/metrics/tab_usage_recorder_browser_agent.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/ntp/new_tab_page_state.h"
 #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h"
 #import "ios/chrome/browser/overscroll_actions/model/overscroll_actions_tab_helper.h"
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
index 5795e2f..daaf3264 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -18,7 +18,6 @@
 #import "ios/chrome/browser/find_in_page/model/util.h"
 #import "ios/chrome/browser/intents/intents_donation_helper.h"
 #import "ios/chrome/browser/metrics/tab_usage_recorder_browser_agent.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h"
 #import "ios/chrome/browser/ntp/new_tab_page_util.h"
 #import "ios/chrome/browser/reading_list/model/reading_list_browser_agent.h"
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller_egtest.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller_egtest.mm
index 258c7bf..ea3daf8 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller_egtest.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller_egtest.mm
@@ -10,7 +10,6 @@
 #import "base/strings/sys_string_conversions.h"
 #import "base/test/ios/wait_util.h"
 #import "components/strings/grit/components_strings.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/shared/model/prefs/pref_names.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
index 292e88c8..678665f 100644
--- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn
+++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -78,7 +78,6 @@
     "//ios/chrome/browser/intents:intents_donation_helper",
     "//ios/chrome/browser/metrics:metrics_internal",
     "//ios/chrome/browser/ntp",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/ntp:set_up_list",
     "//ios/chrome/browser/ntp:set_up_list_item_type",
     "//ios/chrome/browser/ntp:set_up_list_prefs",
@@ -181,6 +180,7 @@
     "//ios/chrome/browser/ntp:set_up_list_metrics",
     "//ios/chrome/browser/ntp/home:features",
     "//ios/chrome/browser/shared/model/prefs:pref_names",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/ui/content_suggestions/cells",
     "//ios/chrome/browser/ui/content_suggestions/cells:constants",
     "//ios/chrome/browser/ui/content_suggestions/set_up_list:utils",
@@ -232,7 +232,6 @@
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/drag_and_drop/model",
     "//ios/chrome/browser/ntp",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/ntp:set_up_list",
     "//ios/chrome/browser/ntp:set_up_list_item_type",
     "//ios/chrome/browser/ntp:set_up_list_prefs",
@@ -290,7 +289,6 @@
     "//base:i18n",
     "//components/strings",
     "//ios/chrome/app/strings",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/ntp/home:features",
     "//ios/chrome/browser/shared/public/commands",
     "//ios/chrome/browser/shared/public/features",
@@ -343,7 +341,6 @@
     "//ios/chrome/browser/favicon",
     "//ios/chrome/browser/first_run",
     "//ios/chrome/browser/ntp",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/ntp:set_up_list_item_type",
     "//ios/chrome/browser/ntp:set_up_list_prefs",
     "//ios/chrome/browser/ntp/home:features",
@@ -420,8 +417,6 @@
     "//components/sync/base:features",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/flags:system_flags",
-    "//ios/chrome/browser/ntp:features",
-    "//ios/chrome/browser/ntp/home:features",
     "//ios/chrome/browser/search_engines/model:eg_test_support+eg2",
     "//ios/chrome/browser/shared/model/prefs:pref_names",
     "//ios/chrome/browser/shared/public/features",
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_cells_constants.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_cells_constants.mm
index 0c9e3d3..25cea4e9 100644
--- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_cells_constants.mm
+++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_cells_constants.mm
@@ -4,8 +4,6 @@
 
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_cells_constants.h"
 
-#import "ios/chrome/browser/ntp/home/features.h"
-
 CGFloat ReturnToRecentTabHeight() {
   return kReturnToRecentTabSize.height;
 }
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_tile_view.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_tile_view.mm
index 6b0f9a7..e7224d9 100644
--- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_tile_view.mm
+++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_tile_view.mm
@@ -5,7 +5,7 @@
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_tile_view.h"
 
 #import "base/check.h"
-#import "ios/chrome/browser/ntp/home/features.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_gesture_commands.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_return_to_recent_tab_view.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_return_to_recent_tab_view.mm
index 3b795de..6ab87732 100644
--- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_return_to_recent_tab_view.mm
+++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_return_to_recent_tab_view.mm
@@ -4,7 +4,7 @@
 
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_return_to_recent_tab_view.h"
 
-#import "ios/chrome/browser/ntp/home/features.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/symbols/symbols.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_return_to_recent_tab_item.h"
 #import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_shortcut_tile_view.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_shortcut_tile_view.mm
index 26f57e6..95eccf0 100644
--- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_shortcut_tile_view.mm
+++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_shortcut_tile_view.mm
@@ -4,7 +4,7 @@
 
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_shortcut_tile_view.h"
 
-#import "ios/chrome/browser/ntp/home/features.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/symbols/symbols.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_action_item.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_tile_view.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_tile_view.mm
index 0ac81b04..513d13b4 100644
--- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_tile_view.mm
+++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_tile_view.mm
@@ -4,7 +4,7 @@
 
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_tile_view.h"
 
-#import "ios/chrome/browser/ntp/home/features.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/util/dynamic_type_util.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_tile_layout_util.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/magic_stack_module_container.mm b/ios/chrome/browser/ui/content_suggestions/cells/magic_stack_module_container.mm
index af19dcc..cf38583 100644
--- a/ios/chrome/browser/ui/content_suggestions/cells/magic_stack_module_container.mm
+++ b/ios/chrome/browser/ui/content_suggestions/cells/magic_stack_module_container.mm
@@ -6,7 +6,7 @@
 
 #import "base/notreached.h"
 #import "base/strings/sys_string_conversions.h"
-#import "ios/chrome/browser/ntp/home/features.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/symbols/symbols.h"
 #import "ios/chrome/browser/shared/ui/util/rtl_geometry.h"
 #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm
index 09dc57c4..9bf415c3 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm
@@ -6,8 +6,6 @@
 
 #import "base/i18n/rtl.h"
 #import "components/strings/grit/components_strings.h"
-#import "ios/chrome/browser/ntp/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/symbols/symbols.h"
 #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils_unittest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils_unittest.mm
index d165eed0..9817ed8 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils_unittest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils_unittest.mm
@@ -7,7 +7,7 @@
 #import <memory>
 
 #import "base/test/scoped_feature_list.h"
-#import "ios/chrome/browser/ntp/features.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/ui/start_surface/start_surface_features.h"
 #import "ios/testing/scoped_block_swizzler.h"
 #import "testing/platform_test.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
index ebd47c23..c4f8fd5 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
@@ -27,7 +27,6 @@
 #import "ios/chrome/browser/favicon/ios_chrome_large_icon_cache_factory.h"
 #import "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h"
 #import "ios/chrome/browser/favicon/large_icon_cache.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h"
 #import "ios/chrome/browser/ntp/set_up_list_item_type.h"
 #import "ios/chrome/browser/ntp/set_up_list_prefs.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm
index b644477d..d8627a8 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm
@@ -13,8 +13,6 @@
 #import "base/test/ios/wait_util.h"
 #import "components/strings/grit/components_strings.h"
 #import "components/sync/base/features.h"
-#import "ios/chrome/browser/ntp/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/shared/model/prefs/pref_names.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/signin/fake_system_identity.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_favicon_mediator.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_favicon_mediator.mm
index a7e9dce..fd32d0b 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_favicon_mediator.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_favicon_mediator.mm
@@ -6,8 +6,8 @@
 
 #import "base/functional/bind.h"
 #import "components/favicon/core/large_icon_service.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/shared/model/application_context/application_context.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_consumer.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm
index 25a78a5..01ffba5 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm
@@ -44,8 +44,6 @@
 #import "ios/chrome/app/application_delegate/app_state_observer.h"
 #import "ios/chrome/browser/default_browser/model/utils.h"
 #import "ios/chrome/browser/intents/intents_donation_helper.h"
-#import "ios/chrome/browser/ntp/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h"
 #import "ios/chrome/browser/ntp/set_up_list.h"
 #import "ios/chrome/browser/ntp/set_up_list_delegate.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator_unittest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator_unittest.mm
index 6086224..32a84831 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator_unittest.mm
@@ -29,8 +29,6 @@
 #import "ios/chrome/browser/favicon/ios_chrome_large_icon_cache_factory.h"
 #import "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h"
 #import "ios/chrome/browser/first_run/first_run.h"
-#import "ios/chrome/browser/ntp/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h"
 #import "ios/chrome/browser/ntp/set_up_list_item_type.h"
 #import "ios/chrome/browser/ntp/set_up_list_prefs.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.mm
index baaf4cf..1895419 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.mm
@@ -13,10 +13,10 @@
 #import "components/ntp_tiles/ntp_tile_impression.h"
 #import "components/ntp_tiles/tile_visual_type.h"
 #import "components/prefs/pref_service.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/ntp/set_up_list_item_type.h"
 #import "ios/chrome/browser/ntp/set_up_list_metrics.h"
 #import "ios/chrome/browser/shared/model/prefs/pref_names.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_tile_constants.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
index 2eeb8eb..09492369 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
@@ -12,7 +12,6 @@
 #import "components/segmentation_platform/public/features.h"
 #import "components/strings/grit/components_strings.h"
 #import "ios/chrome/browser/drag_and_drop/model/url_drag_drop_handler.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/ntp/set_up_list_item.h"
 #import "ios/chrome/browser/ntp/set_up_list_item_type.h"
 #import "ios/chrome/browser/parcel_tracking/parcel_tracking_util.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller_unittest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller_unittest.mm
index 76a4d3f..1c4e6845 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller_unittest.mm
@@ -10,8 +10,6 @@
 #import "components/segmentation_platform/public/features.h"
 #import "components/sync_preferences/testing_pref_service_syncable.h"
 #import "ios/chrome/browser/first_run/first_run.h"
-#import "ios/chrome/browser/ntp/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/safety_check/model/ios_chrome_safety_check_manager_constants.h"
 #import "ios/chrome/browser/shared/model/prefs/pref_names.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/magic_stack_half_sheet_mediator.mm b/ios/chrome/browser/ui/content_suggestions/magic_stack_half_sheet_mediator.mm
index fd0dece..0f148f10 100644
--- a/ios/chrome/browser/ui/content_suggestions/magic_stack_half_sheet_mediator.mm
+++ b/ios/chrome/browser/ui/content_suggestions/magic_stack_half_sheet_mediator.mm
@@ -4,8 +4,6 @@
 
 #import "ios/chrome/browser/ui/content_suggestions/magic_stack_half_sheet_mediator.h"
 
-#import "ios/chrome/browser/ntp/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/ntp/set_up_list_prefs.h"
 #import "ios/chrome/browser/ntp_tiles/model/tab_resumption/tab_resumption_prefs.h"
 #import "ios/chrome/browser/parcel_tracking/parcel_tracking_prefs.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/magic_stack_half_sheet_mediator_unittest.mm b/ios/chrome/browser/ui/content_suggestions/magic_stack_half_sheet_mediator_unittest.mm
index b4c22b98..7f50f33 100644
--- a/ios/chrome/browser/ui/content_suggestions/magic_stack_half_sheet_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/magic_stack_half_sheet_mediator_unittest.mm
@@ -9,8 +9,6 @@
 #import "components/sync_preferences/testing_pref_service_syncable.h"
 #import "ios/chrome/browser/default_browser/model/utils_test_support.h"
 #import "ios/chrome/browser/first_run/first_run.h"
-#import "ios/chrome/browser/ntp/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/ntp/set_up_list_prefs.h"
 #import "ios/chrome/browser/parcel_tracking/features.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/magic_stack_half_sheet_table_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/magic_stack_half_sheet_table_view_controller.mm
index 387e343..080bf96 100644
--- a/ios/chrome/browser/ui/content_suggestions/magic_stack_half_sheet_table_view_controller.mm
+++ b/ios/chrome/browser/ui/content_suggestions/magic_stack_half_sheet_table_view_controller.mm
@@ -5,8 +5,6 @@
 #import "ios/chrome/browser/ui/content_suggestions/magic_stack_half_sheet_table_view_controller.h"
 
 #import "base/apple/foundation_util.h"
-#import "ios/chrome/browser/ntp/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/parcel_tracking/parcel_tracking_util.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/symbols/symbols.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/magic_stack_half_sheet_table_view_controller_unittest.mm b/ios/chrome/browser/ui/content_suggestions/magic_stack_half_sheet_table_view_controller_unittest.mm
index 1a1c8e3..548afa74 100644
--- a/ios/chrome/browser/ui/content_suggestions/magic_stack_half_sheet_table_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/magic_stack_half_sheet_table_view_controller_unittest.mm
@@ -5,8 +5,6 @@
 #import "ios/chrome/browser/ui/content_suggestions/magic_stack_half_sheet_table_view_controller.h"
 
 #import "base/test/scoped_feature_list.h"
-#import "ios/chrome/browser/ntp/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/parcel_tracking/features.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_switch_item.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
index 48cea4e..54be8f6 100644
--- a/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_egtest.mm
@@ -10,8 +10,6 @@
 #import "components/feed/core/v2/public/ios/pref_names.h"
 #import "components/strings/grit/components_strings.h"
 #import "ios/chrome/browser/flags/chrome_switches.h"
-#import "ios/chrome/browser/ntp/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/search_engines/model/search_engines_app_interface.h"
 #import "ios/chrome/browser/shared/model/prefs/pref_names.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/set_up_list/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/set_up_list/BUILD.gn
index 521112e..3a16d70 100644
--- a/ios/chrome/browser/ui/content_suggestions/set_up_list/BUILD.gn
+++ b/ios/chrome/browser/ui/content_suggestions/set_up_list/BUILD.gn
@@ -26,6 +26,7 @@
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/ntp:set_up_list_item_type",
     "//ios/chrome/browser/ntp/home:features",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/shared/ui/elements",
     "//ios/chrome/browser/shared/ui/symbols",
     "//ios/chrome/browser/shared/ui/util",
@@ -78,6 +79,7 @@
     "//ios/chrome/browser/first_run",
     "//ios/chrome/browser/ntp:set_up_list_prefs",
     "//ios/chrome/browser/ntp/home:features",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/ui/first_run:utils",
   ]
 }
diff --git a/ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_icon.mm b/ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_icon.mm
index 2293a64..097e0e8 100644
--- a/ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_icon.mm
+++ b/ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_icon.mm
@@ -8,8 +8,8 @@
 #import "base/task/sequenced_task_runner.h"
 #import "base/time/time.h"
 #import "components/sync/base/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/ntp/set_up_list_item_type.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/symbols/symbols.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_view.mm b/ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_view.mm
index c5ab5580..0e8aca1 100644
--- a/ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_view.mm
+++ b/ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_view.mm
@@ -10,8 +10,8 @@
 #import "base/time/time.h"
 #import "components/password_manager/core/common/password_manager_features.h"
 #import "components/sync/base/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/ntp/set_up_list_item_type.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/elements/crossfade_label.h"
 #import "ios/chrome/browser/shared/ui/symbols/symbols.h"
 #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/set_up_list/utils.mm b/ios/chrome/browser/ui/content_suggestions/set_up_list/utils.mm
index 6b6363a..1888cdd 100644
--- a/ios/chrome/browser/ui/content_suggestions/set_up_list/utils.mm
+++ b/ios/chrome/browser/ui/content_suggestions/set_up_list/utils.mm
@@ -6,8 +6,8 @@
 
 #import "base/time/time.h"
 #import "ios/chrome/browser/first_run/first_run.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/ntp/set_up_list_prefs.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/ui/first_run/first_run_util.h"
 
 namespace set_up_list_utils {
diff --git a/ios/chrome/browser/ui/content_suggestions/tab_resumption/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/tab_resumption/BUILD.gn
index 936cb0837..7ca74be6 100644
--- a/ios/chrome/browser/ui/content_suggestions/tab_resumption/BUILD.gn
+++ b/ios/chrome/browser/ui/content_suggestions/tab_resumption/BUILD.gn
@@ -43,6 +43,7 @@
     "//ios/chrome/browser/shared/model/browser",
     "//ios/chrome/browser/shared/model/browser_state",
     "//ios/chrome/browser/shared/model/web_state_list",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/sync/model",
     "//ios/chrome/browser/synced_sessions/model",
     "//ios/chrome/browser/tabs/model:tab_sync_util",
@@ -73,6 +74,7 @@
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/ntp/home:features",
     "//ios/chrome/browser/ntp_tiles/model/tab_resumption:tab_resumption_prefs",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/signin:fake_system_identity",
     "//ios/chrome/browser/ui/authentication:eg_test_support+eg2",
     "//ios/chrome/browser/ui/content_suggestions:constants",
diff --git a/ios/chrome/browser/ui/content_suggestions/tab_resumption/tab_resumption_egtest.mm b/ios/chrome/browser/ui/content_suggestions/tab_resumption/tab_resumption_egtest.mm
index a6e3759..1ec93de3 100644
--- a/ios/chrome/browser/ui/content_suggestions/tab_resumption/tab_resumption_egtest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/tab_resumption/tab_resumption_egtest.mm
@@ -6,8 +6,8 @@
 #import "base/test/ios/wait_util.h"
 #import "components/sync/base/features.h"
 #import "components/url_formatter/elide_url.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/ntp_tiles/model/tab_resumption/tab_resumption_prefs.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/signin/fake_system_identity.h"
 #import "ios/chrome/browser/ui/authentication/signin_earl_grey.h"
 #import "ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.h"
diff --git a/ios/chrome/browser/ui/content_suggestions/tab_resumption/tab_resumption_helper.mm b/ios/chrome/browser/ui/content_suggestions/tab_resumption/tab_resumption_helper.mm
index 195fdfd4..474a731 100644
--- a/ios/chrome/browser/ui/content_suggestions/tab_resumption/tab_resumption_helper.mm
+++ b/ios/chrome/browser/ui/content_suggestions/tab_resumption/tab_resumption_helper.mm
@@ -12,13 +12,13 @@
 #import "ios/chrome/browser/favicon/favicon_loader.h"
 #import "ios/chrome/browser/favicon/ios_chrome_favicon_loader_factory.h"
 #import "ios/chrome/browser/metrics/new_tab_page_uma.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/sessions/session_util.h"
 #import "ios/chrome/browser/shared/coordinator/scene/scene_state_browser_agent.h"
 #import "ios/chrome/browser/shared/model/browser/browser.h"
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h"
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_opener.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/sync/model/session_sync_service_factory.h"
 #import "ios/chrome/browser/sync/model/sync_service_factory.h"
 #import "ios/chrome/browser/synced_sessions/model/distant_session.h"
diff --git a/ios/chrome/browser/ui/follow/BUILD.gn b/ios/chrome/browser/ui/follow/BUILD.gn
index 85b0345..0ce3635 100644
--- a/ios/chrome/browser/ui/follow/BUILD.gn
+++ b/ios/chrome/browser/ui/follow/BUILD.gn
@@ -63,7 +63,7 @@
     ":follow",
     "//base",
     "//ios/chrome/app/strings",
-    "//ios/chrome/browser/ntp:features",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/shared/ui/symbols",
     "//ios/chrome/common/ui/colors",
     "//ios/chrome/common/ui/confirmation_alert",
diff --git a/ios/chrome/browser/ui/follow/first_follow_view_controller.mm b/ios/chrome/browser/ui/follow/first_follow_view_controller.mm
index 5d3144e..363c528 100644
--- a/ios/chrome/browser/ui/follow/first_follow_view_controller.mm
+++ b/ios/chrome/browser/ui/follow/first_follow_view_controller.mm
@@ -5,7 +5,7 @@
 #import "ios/chrome/browser/ui/follow/first_follow_view_controller.h"
 
 #import "base/strings/sys_string_conversions.h"
-#import "ios/chrome/browser/ntp/features.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/symbols/symbols.h"
 #import "ios/chrome/browser/ui/follow/followed_web_channel.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
diff --git a/ios/chrome/browser/ui/history/history_table_view_controller.mm b/ios/chrome/browser/ui/history/history_table_view_controller.mm
index 77af4cf..7ffc3385 100644
--- a/ios/chrome/browser/ui/history/history_table_view_controller.mm
+++ b/ios/chrome/browser/ui/history/history_table_view_controller.mm
@@ -510,7 +510,14 @@
   if (!self.historyService)
     return;
 
+  // Validate indexes of items to delete and abort if any have been made invalid
+  // by a crossing actions (like query refresh or animations).
   NSArray* toDeleteIndexPaths = self.tableView.indexPathsForSelectedRows;
+  for (NSIndexPath* indexPath in toDeleteIndexPaths) {
+    if (![self.tableViewModel hasItemAtIndexPath:indexPath]) {
+      return;
+    }
+  }
 
   // Delete items from Browser History.
   std::vector<BrowsingHistoryService::HistoryEntry> entries;
@@ -606,7 +613,11 @@
     // Don't show the context menu when currently in editing mode.
     return nil;
   }
-
+  if (![self.tableViewModel hasItemAtIndexPath:indexPath]) {
+    // It's possible that indexPath is invalid due to crossing action (like
+    // query refresh or animations).
+    return nil;
+  }
   if (indexPath.section ==
       [self.tableViewModel
           sectionForSectionIdentifier:kEntriesStatusSectionIdentifier]) {
diff --git a/ios/chrome/browser/ui/ntp/BUILD.gn b/ios/chrome/browser/ui/ntp/BUILD.gn
index 993f687a..ea706c1 100644
--- a/ios/chrome/browser/ui/ntp/BUILD.gn
+++ b/ios/chrome/browser/ui/ntp/BUILD.gn
@@ -104,8 +104,6 @@
     "//ios/chrome/browser/follow:enums",
     "//ios/chrome/browser/follow:service",
     "//ios/chrome/browser/ntp",
-    "//ios/chrome/browser/ntp:features",
-    "//ios/chrome/browser/ntp/home:features",
     "//ios/chrome/browser/search_engines/model:template_url_service_factory",
     "//ios/chrome/browser/shared/coordinator/chrome_coordinator",
     "//ios/chrome/browser/shared/coordinator/layout_guide",
@@ -213,8 +211,6 @@
     "//ios/chrome/browser/discover_feed:discover_feed_factory",
     "//ios/chrome/browser/metrics:metrics_internal",
     "//ios/chrome/browser/ntp",
-    "//ios/chrome/browser/ntp:features",
-    "//ios/chrome/browser/ntp/home:features",
     "//ios/chrome/browser/policy:policy_util",
     "//ios/chrome/browser/search_engines/model",
     "//ios/chrome/browser/shared/model/browser_state",
@@ -281,12 +277,12 @@
     "//components/feed/core/v2/public/ios:feed_ios_public",
     "//components/prefs",
     "//ios/chrome/app/strings",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/shared/coordinator/alert",
     "//ios/chrome/browser/shared/coordinator/chrome_coordinator",
     "//ios/chrome/browser/shared/model/browser",
     "//ios/chrome/browser/shared/model/browser_state",
     "//ios/chrome/browser/shared/public/commands",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/signin",
     "//ui/strings",
   ]
@@ -321,7 +317,6 @@
     "//ios/chrome/browser/discover_feed:discover_feed_factory",
     "//ios/chrome/browser/favicon",
     "//ios/chrome/browser/ntp",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/search_engines/model:template_url_service_factory",
     "//ios/chrome/browser/shared/coordinator/scene:scene_state_browser_agent",
     "//ios/chrome/browser/shared/coordinator/scene:scene_state_header",
@@ -332,6 +327,7 @@
     "//ios/chrome/browser/shared/model/url:constants",
     "//ios/chrome/browser/shared/model/web_state_list",
     "//ios/chrome/browser/shared/public/commands",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/signin",
     "//ios/chrome/browser/signin:fake_system_identity",
     "//ios/chrome/browser/signin:fake_system_identity_manager",
@@ -393,6 +389,7 @@
     "//ios/chrome/browser/ntp/home:features",
     "//ios/chrome/browser/shared/model/application_context",
     "//ios/chrome/browser/shared/model/prefs:pref_names",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/ui/authentication/cells:constants",
   ]
   public_deps = [ "//base" ]
diff --git a/ios/chrome/browser/ui/ntp/feed_header_view_controller.mm b/ios/chrome/browser/ui/ntp/feed_header_view_controller.mm
index d3dcb69..efe432f 100644
--- a/ios/chrome/browser/ui/ntp/feed_header_view_controller.mm
+++ b/ios/chrome/browser/ui/ntp/feed_header_view_controller.mm
@@ -4,8 +4,7 @@
 
 #import "ios/chrome/browser/ui/ntp/feed_header_view_controller.h"
 
-#import "ios/chrome/browser/ntp/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/symbols/symbols.h"
 #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
 #import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h"
diff --git a/ios/chrome/browser/ui/ntp/feed_management/BUILD.gn b/ios/chrome/browser/ui/ntp/feed_management/BUILD.gn
index b8efdc9..f2dac0f 100644
--- a/ios/chrome/browser/ui/ntp/feed_management/BUILD.gn
+++ b/ios/chrome/browser/ui/ntp/feed_management/BUILD.gn
@@ -33,7 +33,7 @@
   deps = [
     ":navigation_delegate",
     "//ios/chrome/app/strings",
-    "//ios/chrome/browser/ntp:features",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/shared/ui/table_view",
     "//ios/chrome/browser/shared/ui/table_view/cells",
     "//ui/base",
@@ -95,7 +95,7 @@
   sources = [ "feed_management_egtest.mm" ]
   deps = [
     "//ios/chrome/app/strings",
-    "//ios/chrome/browser/ntp:features",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/signin:fake_system_identity",
     "//ios/chrome/browser/ui/authentication:eg_test_support+eg2",
     "//ios/chrome/test/earl_grey:eg_test_support+eg2",
diff --git a/ios/chrome/browser/ui/ntp/feed_management/feed_management_egtest.mm b/ios/chrome/browser/ui/ntp/feed_management/feed_management_egtest.mm
index 8dda1d6..8d1c88fe 100644
--- a/ios/chrome/browser/ui/ntp/feed_management/feed_management_egtest.mm
+++ b/ios/chrome/browser/ui/ntp/feed_management/feed_management_egtest.mm
@@ -5,7 +5,7 @@
 #import <UIKit/UIKit.h>
 #import <XCTest/XCTest.h>
 
-#import "ios/chrome/browser/ntp/features.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/signin/fake_system_identity.h"
 #import "ios/chrome/browser/ui/authentication/signin_earl_grey.h"
 #import "ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.h"
diff --git a/ios/chrome/browser/ui/ntp/feed_management/feed_management_view_controller.mm b/ios/chrome/browser/ui/ntp/feed_management/feed_management_view_controller.mm
index 6ba01d4..f229969 100644
--- a/ios/chrome/browser/ui/ntp/feed_management/feed_management_view_controller.mm
+++ b/ios/chrome/browser/ui/ntp/feed_management/feed_management_view_controller.mm
@@ -4,7 +4,7 @@
 
 #import "ios/chrome/browser/ui/ntp/feed_management/feed_management_view_controller.h"
 
-#import "ios/chrome/browser/ntp/features.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_detail_text_item.h"
 #import "ios/chrome/browser/ui/ntp/feed_management/feed_management_follow_delegate.h"
 #import "ios/chrome/browser/ui/ntp/feed_management/feed_management_navigation_delegate.h"
diff --git a/ios/chrome/browser/ui/ntp/feed_menu_coordinator.mm b/ios/chrome/browser/ui/ntp/feed_menu_coordinator.mm
index 23ec7c7..74767ee 100644
--- a/ios/chrome/browser/ui/ntp/feed_menu_coordinator.mm
+++ b/ios/chrome/browser/ui/ntp/feed_menu_coordinator.mm
@@ -6,11 +6,11 @@
 
 #import "components/feed/core/v2/public/ios/pref_names.h"
 #import "components/prefs/pref_service.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/shared/coordinator/alert/action_sheet_coordinator.h"
 #import "ios/chrome/browser/shared/model/browser/browser.h"
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/signin/authentication_service.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/grit/ios_strings.h"
diff --git a/ios/chrome/browser/ui/ntp/feed_menu_coordinator_unittest.mm b/ios/chrome/browser/ui/ntp/feed_menu_coordinator_unittest.mm
index 2948d90..f9099077 100644
--- a/ios/chrome/browser/ui/ntp/feed_menu_coordinator_unittest.mm
+++ b/ios/chrome/browser/ui/ntp/feed_menu_coordinator_unittest.mm
@@ -8,10 +8,10 @@
 #import "base/test/scoped_feature_list.h"
 #import "components/feed/core/v2/public/ios/pref_names.h"
 #import "components/prefs/pref_service.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/shared/model/application_context/application_context.h"
 #import "ios/chrome/browser/shared/model/browser/test/test_browser.h"
 #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/signin/authentication_service.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/signin/fake_authentication_service_delegate.h"
diff --git a/ios/chrome/browser/ui/ntp/feed_promos/BUILD.gn b/ios/chrome/browser/ui/ntp/feed_promos/BUILD.gn
index e5a4460d..1846b022 100644
--- a/ios/chrome/browser/ui/ntp/feed_promos/BUILD.gn
+++ b/ios/chrome/browser/ui/ntp/feed_promos/BUILD.gn
@@ -12,7 +12,6 @@
     ":feed_promos_ui",
     "//ios/chrome/browser/discover_feed",
     "//ios/chrome/browser/discover_feed:discover_feed_factory",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/shared/coordinator/chrome_coordinator",
     "//ios/chrome/browser/shared/model/browser",
     "//ios/chrome/browser/shared/public/commands",
diff --git a/ios/chrome/browser/ui/ntp/feed_promos/feed_sign_in_promo_coordinator.mm b/ios/chrome/browser/ui/ntp/feed_promos/feed_sign_in_promo_coordinator.mm
index 87b66d4..99c40dd2 100644
--- a/ios/chrome/browser/ui/ntp/feed_promos/feed_sign_in_promo_coordinator.mm
+++ b/ios/chrome/browser/ui/ntp/feed_promos/feed_sign_in_promo_coordinator.mm
@@ -7,7 +7,6 @@
 #import "components/signin/public/base/signin_metrics.h"
 #import "ios/chrome/browser/discover_feed/discover_feed_service.h"
 #import "ios/chrome/browser/discover_feed/discover_feed_service_factory.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/shared/model/browser/browser.h"
 #import "ios/chrome/browser/shared/public/commands/application_commands.h"
 #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
diff --git a/ios/chrome/browser/ui/ntp/feed_top_section/BUILD.gn b/ios/chrome/browser/ui/ntp/feed_top_section/BUILD.gn
index 7f12e08..8e1fbc9 100644
--- a/ios/chrome/browser/ui/ntp/feed_top_section/BUILD.gn
+++ b/ios/chrome/browser/ui/ntp/feed_top_section/BUILD.gn
@@ -18,13 +18,12 @@
     "//components/sync/base:features",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/discover_feed:constants",
-    "//ios/chrome/browser/ntp:features",
-    "//ios/chrome/browser/ntp/home:features",
     "//ios/chrome/browser/shared/coordinator/chrome_coordinator",
     "//ios/chrome/browser/shared/model/application_context",
     "//ios/chrome/browser/shared/model/browser",
     "//ios/chrome/browser/shared/model/browser_state",
     "//ios/chrome/browser/shared/public/commands",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/signin",
     "//ios/chrome/browser/sync/model",
     "//ios/chrome/browser/ui/authentication",
diff --git a/ios/chrome/browser/ui/ntp/feed_top_section/feed_top_section_mediator.mm b/ios/chrome/browser/ui/ntp/feed_top_section/feed_top_section_mediator.mm
index b816071..5a9db7c 100644
--- a/ios/chrome/browser/ui/ntp/feed_top_section/feed_top_section_mediator.mm
+++ b/ios/chrome/browser/ui/ntp/feed_top_section/feed_top_section_mediator.mm
@@ -8,8 +8,8 @@
 #import "components/signin/public/identity_manager/identity_manager.h"
 #import "components/signin/public/identity_manager/objc/identity_manager_observer_bridge.h"
 #import "components/sync/base/features.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/shared/model/application_context/application_context.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/signin/identity_manager_factory.h"
 #import "ios/chrome/browser/ui/authentication/signin_promo_view_mediator.h"
diff --git a/ios/chrome/browser/ui/ntp/feed_top_section/feed_top_section_view_controller.mm b/ios/chrome/browser/ui/ntp/feed_top_section/feed_top_section_view_controller.mm
index 446d251f3..d66c509 100644
--- a/ios/chrome/browser/ui/ntp/feed_top_section/feed_top_section_view_controller.mm
+++ b/ios/chrome/browser/ui/ntp/feed_top_section/feed_top_section_view_controller.mm
@@ -8,7 +8,7 @@
 #import "base/feature_list.h"
 #import "components/sync/base/features.h"
 #import "ios/chrome/browser/discover_feed/feed_constants.h"
-#import "ios/chrome/browser/ntp/home/features.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/ui/authentication/cells/signin_promo_view.h"
 #import "ios/chrome/browser/ui/authentication/cells/signin_promo_view_configurator.h"
 #import "ios/chrome/browser/ui/authentication/cells/signin_promo_view_constants.h"
diff --git a/ios/chrome/browser/ui/ntp/feed_wrapper_view_controller.mm b/ios/chrome/browser/ui/ntp/feed_wrapper_view_controller.mm
index 29c95b6..122bc41 100644
--- a/ios/chrome/browser/ui/ntp/feed_wrapper_view_controller.mm
+++ b/ios/chrome/browser/ui/ntp/feed_wrapper_view_controller.mm
@@ -5,7 +5,7 @@
 #import <UIKit/UIKit.h>
 
 #import "base/check.h"
-#import "ios/chrome/browser/ntp/home/features.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h"
 #import "ios/chrome/browser/ui/ntp/feed_wrapper_view_controller.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
diff --git a/ios/chrome/browser/ui/ntp/metrics/BUILD.gn b/ios/chrome/browser/ui/ntp/metrics/BUILD.gn
index 228371a2..5887f1e0 100644
--- a/ios/chrome/browser/ui/ntp/metrics/BUILD.gn
+++ b/ios/chrome/browser/ui/ntp/metrics/BUILD.gn
@@ -25,8 +25,8 @@
     "//ios/chrome/browser/discover_feed:constants",
     "//ios/chrome/browser/discover_feed:discover_feed_refresher",
     "//ios/chrome/browser/metrics:constants",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/shared/model/prefs:pref_names",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/ui/content_suggestions:constants",
     "//ios/chrome/browser/ui/content_suggestions:metrics",
     "//ios/chrome/browser/ui/favicon",
diff --git a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.mm b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.mm
index f63de49..f203dfe5 100644
--- a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.mm
+++ b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_recorder.mm
@@ -14,7 +14,7 @@
 #import "components/prefs/pref_service.h"
 #import "ios/chrome/browser/discover_feed/discover_feed_refresher.h"
 #import "ios/chrome/browser/metrics/constants.h"
-#import "ios/chrome/browser/ntp/features.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/ui/ntp/feed_control_delegate.h"
 #import "ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.h"
 #import "ios/chrome/browser/ui/ntp/metrics/feed_session_recorder.h"
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
index 8a8555a..7524d0a 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
@@ -35,8 +35,6 @@
 #import "ios/chrome/browser/follow/follow_browser_agent.h"
 #import "ios/chrome/browser/follow/followed_web_site.h"
 #import "ios/chrome/browser/follow/followed_web_site_state.h"
-#import "ios/chrome/browser/ntp/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/ntp/new_tab_page_state.h"
 #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h"
 #import "ios/chrome/browser/search_engines/model/template_url_service_factory.h"
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_feature.mm b/ios/chrome/browser/ui/ntp/new_tab_page_feature.mm
index 1798234..28f4a02 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_feature.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_feature.mm
@@ -7,9 +7,9 @@
 #import "base/ios/ios_util.h"
 #import "base/metrics/field_trial_params.h"
 #import "components/variations/service/variations_service.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/shared/model/application_context/application_context.h"
 #import "ios/chrome/browser/shared/model/prefs/pref_names.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 
 #pragma mark - Constants
 
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm b/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm
index 71b4499..7fea497 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm
@@ -11,8 +11,6 @@
 #import "base/check.h"
 #import "base/feature_list.h"
 #import "components/strings/grit/components_strings.h"
-#import "ios/chrome/browser/ntp/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/elements/extended_touch_target_button.h"
 #import "ios/chrome/browser/shared/ui/util/dynamic_type_util.h"
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm b/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm
index d8feedee3..3b14354 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm
@@ -14,8 +14,6 @@
 #import "components/signin/public/base/signin_switches.h"
 #import "components/strings/grit/components_strings.h"
 #import "components/sync/base/features.h"
-#import "ios/chrome/browser/ntp/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h"
 #import "ios/chrome/browser/shared/public/commands/application_commands.h"
 #import "ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h"
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_mediator.mm b/ios/chrome/browser/ui/ntp/new_tab_page_mediator.mm
index c67b819c..efcea9f 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_mediator.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_mediator.mm
@@ -16,8 +16,6 @@
 #import "ios/chrome/browser/discover_feed/discover_feed_service.h"
 #import "ios/chrome/browser/discover_feed/discover_feed_service_factory.h"
 #import "ios/chrome/browser/metrics/new_tab_page_uma.h"
-#import "ios/chrome/browser/ntp/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/ntp/new_tab_page_state.h"
 #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h"
 #import "ios/chrome/browser/policy/policy_util.h"
@@ -25,6 +23,7 @@
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/shared/model/prefs/pref_names.h"
 #import "ios/chrome/browser/shared/model/url/chrome_url_constants.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
 #import "ios/chrome/browser/signin/authentication_service.h"
 #import "ios/chrome/browser/signin/chrome_account_manager_service.h"
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_mediator_unittest.mm b/ios/chrome/browser/ui/ntp/new_tab_page_mediator_unittest.mm
index aff5ffa..b2e7b1a 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_mediator_unittest.mm
@@ -15,13 +15,13 @@
 #import "components/search_engines/template_url_service.h"
 #import "components/signin/public/identity_manager/identity_manager.h"
 #import "ios/chrome/browser/discover_feed/discover_feed_service_factory.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h"
 #import "ios/chrome/browser/search_engines/model/template_url_service_factory.h"
 #import "ios/chrome/browser/shared/model/browser/browser.h"
 #import "ios/chrome/browser/shared/model/browser/test/test_browser.h"
 #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h"
 #import "ios/chrome/browser/shared/model/url/chrome_url_constants.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/signin/chrome_account_manager_service_factory.h"
 #import "ios/chrome/browser/signin/fake_authentication_service_delegate.h"
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm
index 18ef7b7..3f0ae7e 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm
@@ -11,8 +11,7 @@
 #import "base/check.h"
 #import "base/ios/block_types.h"
 #import "base/task/sequenced_task_runner.h"
-#import "ios/chrome/browser/ntp/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
 #import "ios/chrome/browser/ui/bubble/bubble_presenter.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_cells_constants.h"
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_ui_features.cc b/ios/chrome/browser/ui/omnibox/omnibox_ui_features.cc
index 2695655..fa2b2410 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_ui_features.cc
+++ b/ios/chrome/browser/ui/omnibox/omnibox_ui_features.cc
@@ -5,7 +5,6 @@
 #import "ios/chrome/browser/ui/omnibox/omnibox_ui_features.h"
 
 #include "base/metrics/field_trial_params.h"
-#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ui/base/device_form_factor.h"
 
 BASE_FEATURE(kEnableSuggestionsScrollingOnIPad,
diff --git a/ios/chrome/browser/ui/orchestrator/BUILD.gn b/ios/chrome/browser/ui/orchestrator/BUILD.gn
index 9931fbc..3f302ae 100644
--- a/ios/chrome/browser/ui/orchestrator/BUILD.gn
+++ b/ios/chrome/browser/ui/orchestrator/BUILD.gn
@@ -13,7 +13,7 @@
   ]
   deps = [
     "//base",
-    "//ios/chrome/browser/ntp:features",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/common:timing",
   ]
   frameworks = [ "UIKit.framework" ]
diff --git a/ios/chrome/browser/ui/orchestrator/omnibox_focus_orchestrator.mm b/ios/chrome/browser/ui/orchestrator/omnibox_focus_orchestrator.mm
index 85bb39b..044a984 100644
--- a/ios/chrome/browser/ui/orchestrator/omnibox_focus_orchestrator.mm
+++ b/ios/chrome/browser/ui/orchestrator/omnibox_focus_orchestrator.mm
@@ -5,7 +5,7 @@
 #import "ios/chrome/browser/ui/orchestrator/omnibox_focus_orchestrator.h"
 
 #import "base/check.h"
-#import "ios/chrome/browser/ntp/features.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/ui/orchestrator/edit_view_animatee.h"
 #import "ios/chrome/browser/ui/orchestrator/location_bar_animatee.h"
 #import "ios/chrome/browser/ui/orchestrator/toolbar_animatee.h"
diff --git a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.mm b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.mm
index 1695899b..7f9c836 100644
--- a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.mm
+++ b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.mm
@@ -11,7 +11,7 @@
 #import "base/numerics/math_constants.h"
 #import "base/task/sequenced_task_runner.h"
 #import "base/time/time.h"
-#import "ios/chrome/browser/ntp/home/features.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/symbols/symbols.h"
 #import "ios/chrome/browser/shared/ui/util/rtl_geometry.h"
 #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
diff --git a/ios/chrome/browser/ui/popup_menu/BUILD.gn b/ios/chrome/browser/ui/popup_menu/BUILD.gn
index 6f0841e..8606f1e 100644
--- a/ios/chrome/browser/ui/popup_menu/BUILD.gn
+++ b/ios/chrome/browser/ui/popup_menu/BUILD.gn
@@ -68,7 +68,6 @@
     "//ios/chrome/browser/follow:tab_helper",
     "//ios/chrome/browser/follow:utils",
     "//ios/chrome/browser/iph_for_new_chrome_user/model",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/overlays",
     "//ios/chrome/browser/overlays/public/web_content_area",
     "//ios/chrome/browser/policy",
diff --git a/ios/chrome/browser/ui/popup_menu/cells/BUILD.gn b/ios/chrome/browser/ui/popup_menu/cells/BUILD.gn
index 7dcf9f9..39c74b1e 100644
--- a/ios/chrome/browser/ui/popup_menu/cells/BUILD.gn
+++ b/ios/chrome/browser/ui/popup_menu/cells/BUILD.gn
@@ -11,7 +11,6 @@
   ]
   deps = [
     "//base",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/shared/ui/table_view:styler",
     "//ios/chrome/browser/shared/ui/table_view/cells",
     "//ios/chrome/browser/ui/popup_menu/public:ui_constants",
diff --git a/ios/chrome/browser/ui/popup_menu/cells/popup_menu_tools_item.mm b/ios/chrome/browser/ui/popup_menu/cells/popup_menu_tools_item.mm
index 0bf77f73..4d2f6daa 100644
--- a/ios/chrome/browser/ui/popup_menu/cells/popup_menu_tools_item.mm
+++ b/ios/chrome/browser/ui/popup_menu/cells/popup_menu_tools_item.mm
@@ -6,7 +6,7 @@
 
 #import <stdlib.h>
 
-#import "ios/chrome/browser/ntp/features.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/table_view/legacy_chrome_table_view_styler.h"
 #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
 #import "ios/chrome/browser/ui/popup_menu/public/popup_menu_ui_constants.h"
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn b/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn
index c3c9183c..b971612 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/BUILD.gn
@@ -38,6 +38,7 @@
     "//components/reading_list/core",
     "//components/reading_list/ios",
     "//components/supervised_user/core/browser",
+    "//components/supervised_user/core/browser:supervised_user_preferences",
     "//components/supervised_user/core/common",
     "//components/sync/service",
     "//components/translate/core/browser",
@@ -51,7 +52,6 @@
     "//ios/chrome/browser/follow:tab_helper",
     "//ios/chrome/browser/follow:utils",
     "//ios/chrome/browser/intents:intents_donation_helper",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/overlays",
     "//ios/chrome/browser/policy",
     "//ios/chrome/browser/policy:policy_util",
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.h b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.h
index 3995f95..5e14d8c 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.h
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.h
@@ -20,9 +20,6 @@
 namespace web {
 class WebState;
 }
-namespace supervised_user {
-class SupervisedUserService;
-}
 namespace syncer {
 class SyncService;
 }
@@ -120,10 +117,6 @@
 // The Sync Service that provides the status of Sync.
 @property(nonatomic, assign) syncer::SyncService* syncService;
 
-// Service that describes the supervision state of the account.
-@property(nonatomic, assign)
-    supervised_user::SupervisedUserService* supervisedUserService;
-
 // The Promos Manager to alert if the user uses What's New.
 @property(nonatomic, assign) PromosManager* promosManager;
 
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm
index 11a2a1f..fc7a83f 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm
@@ -24,7 +24,7 @@
 #import "components/profile_metrics/browser_profile_type.h"
 #import "components/reading_list/core/reading_list_model.h"
 #import "components/reading_list/ios/reading_list_model_bridge_observer.h"
-#import "components/supervised_user/core/browser/supervised_user_service.h"
+#import "components/supervised_user/core/browser/supervised_user_preferences.h"
 #import "components/supervised_user/core/common/features.h"
 #import "components/sync/service/sync_service.h"
 #import "components/translate/core/browser/translate_manager.h"
@@ -38,7 +38,6 @@
 #import "ios/chrome/browser/follow/follow_tab_helper.h"
 #import "ios/chrome/browser/follow/follow_util.h"
 #import "ios/chrome/browser/intents/intents_donation_helper.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/overlays/public/overlay_presenter.h"
 #import "ios/chrome/browser/overlays/public/overlay_presenter_observer_bridge.h"
 #import "ios/chrome/browser/overlays/public/overlay_request.h"
@@ -440,17 +439,6 @@
   [self updateModel];
 }
 
-- (void)setSupervisedUserService:
-    (supervised_user::SupervisedUserService*)supervisedUserService {
-  _supervisedUserService = supervisedUserService;
-
-  if (!supervisedUserService) {
-    return;
-  }
-
-  [self updateModel];
-}
-
 #pragma mark - Model Creation
 
 - (void)initializeModel {
@@ -1244,6 +1232,10 @@
       _authenticationService && _browserStatePrefs &&
       CanFetchUserPolicy(_authenticationService, _browserStatePrefs);
   // Set footer (on last section), if any.
+  auto* browser_state =
+      self.webState ? self.webState->GetBrowserState() : nullptr;
+  auto* chrome_browser_state =
+      ChromeBrowserState::FromBrowserState(browser_state);
   if (hasMachineLevelPolicies || canFetchUserPolicies) {
     // Set the Enterprise footer if there are machine level or user level
     // (aka ChromeBrowserState level) policies.
@@ -1253,8 +1245,8 @@
         @"overflow_menu_footer_managed", ^{
           [self enterpriseLearnMore];
         });
-  } else if (self.supervisedUserService &&
-             self.supervisedUserService->IsSubjectToParentalControls()) {
+  } else if (chrome_browser_state && supervised_user::IsChildAccount(
+                                         *chrome_browser_state->GetPrefs())) {
     self.helpActionsGroup.footer = CreateOverflowMenuManagedFooter(
         IDS_IOS_TOOLS_MENU_PARENT_MANAGED, IDS_IOS_TOOLS_MENU_PARENT_LEARN_MORE,
         kTextMenuFamilyLinkInfo, @"overflow_menu_footer_family_link", ^{
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator_unittest.mm b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator_unittest.mm
index 661ee73..d3861fae 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator_unittest.mm
@@ -264,8 +264,6 @@
     mediator_.isIncognito = is_incognito;
     mediator_.menuOrderer = orderer_;
     mediator_.baseViewController = baseViewController_;
-    mediator_.supervisedUserService =
-        SupervisedUserServiceFactory::GetForBrowserState(browser_state_.get());
     SetUpReadingList();
     return mediator_;
   }
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
index f633f3e..7d0366b 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
@@ -18,7 +18,6 @@
 #import "ios/chrome/browser/feature_engagement/model/tracker_factory.h"
 #import "ios/chrome/browser/follow/follow_action_state.h"
 #import "ios/chrome/browser/follow/follow_browser_agent.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/overlays/public/overlay_presenter.h"
 #import "ios/chrome/browser/promos_manager/promos_manager_factory.h"
 #import "ios/chrome/browser/reading_list/model/reading_list_browser_agent.h"
@@ -48,6 +47,7 @@
 #import "ios/chrome/browser/shared/public/commands/qr_scanner_commands.h"
 #import "ios/chrome/browser/shared/public/commands/snackbar_commands.h"
 #import "ios/chrome/browser/shared/public/commands/text_zoom_commands.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/util/layout_guide_names.h"
 #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
 #import "ios/chrome/browser/shared/ui/util/util_swift.h"
@@ -314,9 +314,6 @@
           GetApplicationContext()->GetBrowserPolicyConnector();
       mediator.syncService = SyncServiceFactory::GetForBrowserState(
           self.browser->GetBrowserState());
-      mediator.supervisedUserService =
-          SupervisedUserServiceFactory::GetForBrowserState(
-              self.browser->GetBrowserState());
       mediator.promosManager = PromosManagerFactory::GetForBrowserState(
           self.browser->GetBrowserState());
       mediator.readingListBrowserAgent =
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm
index a21dd22a..9372f19 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_mediator.mm
@@ -34,7 +34,6 @@
 #import "ios/chrome/browser/follow/follow_menu_updater.h"
 #import "ios/chrome/browser/follow/follow_tab_helper.h"
 #import "ios/chrome/browser/follow/follow_util.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/overlays/public/overlay_presenter.h"
 #import "ios/chrome/browser/overlays/public/overlay_presenter_observer_bridge.h"
 #import "ios/chrome/browser/overlays/public/overlay_request.h"
diff --git a/ios/chrome/browser/ui/post_restore_signin/BUILD.gn b/ios/chrome/browser/ui/post_restore_signin/BUILD.gn
index bbc8196c..c0dfd17 100644
--- a/ios/chrome/browser/ui/post_restore_signin/BUILD.gn
+++ b/ios/chrome/browser/ui/post_restore_signin/BUILD.gn
@@ -23,6 +23,7 @@
     "//ios/chrome/browser/shared/ui/util",
     "//ios/chrome/browser/signin:signin_util",
     "//ios/chrome/browser/ui/authentication:authentication_constants",
+    "//ios/chrome/browser/ui/authentication/signin:constants",
     "//ios/chrome/browser/ui/authentication/views",
     "//ios/chrome/common/ui/confirmation_alert",
     "//ios/chrome/common/ui/promo_style:promo_style",
@@ -42,6 +43,7 @@
     ":post_restore_signin",
     "//base",
     "//base/test:test_support",
+    "//components/sync:test_support",
     "//ios/chrome/browser/signin:signin_util",
     "//ios/chrome/test:test_support",
     "//third_party/ocmock",
diff --git a/ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider.h b/ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider.h
index 42611128..898ecf2 100644
--- a/ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider.h
+++ b/ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider.h
@@ -9,6 +9,10 @@
 #import "ios/chrome/browser/ui/promos_manager/bannered_promo_view_provider.h"
 #import "ios/chrome/browser/ui/promos_manager/standard_promo_alert_provider.h"
 
+namespace syncer {
+class SyncUserSettings;
+}  // namespace syncer
+
 // Provider for displaying the Post Restore Sign-in Promo.
 //
 // The Post Restore Sign-in promo comes in two variations: (1) A fullscreen,
@@ -16,7 +20,12 @@
 // necessary data and functionality to power both variations of this promo.
 @interface PostRestoreSignInProvider : NSObject <StandardPromoAlertProvider>
 
-- (instancetype)init;
+// `syncUserSettings` is used to enabled history sync opt-in after restore if it
+// was previously enabled.
+- (instancetype)initWithSyncUserSettings:
+    (syncer::SyncUserSettings*)syncUserSettings NS_DESIGNATED_INITIALIZER;
+
+- (instancetype)init NS_UNAVAILABLE;
 
 // Delegate callback to tell the provider that the promo was displayed.
 - (void)promoWasDisplayed;
diff --git a/ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider.mm b/ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider.mm
index 371bc7c..c1d2afb 100644
--- a/ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider.mm
+++ b/ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider.mm
@@ -10,11 +10,14 @@
 #import "base/strings/sys_string_conversions.h"
 #import "components/feature_engagement/public/feature_constants.h"
 #import "components/signin/public/identity_manager/account_info.h"
+#import "components/sync/base/features.h"
+#import "components/sync/service/sync_user_settings.h"
 #import "ios/chrome/browser/promos_manager/constants.h"
 #import "ios/chrome/browser/promos_manager/promo_config.h"
 #import "ios/chrome/browser/shared/model/application_context/application_context.h"
 #import "ios/chrome/browser/shared/public/commands/show_signin_command.h"
 #import "ios/chrome/browser/signin/signin_util.h"
+#import "ios/chrome/browser/ui/authentication/signin/signin_constants.h"
 #import "ios/chrome/browser/ui/post_restore_signin/metrics.h"
 #import "ios/chrome/browser/ui/post_restore_signin/post_restore_signin_view_controller.h"
 #import "ios/chrome/common/ui/promo_style/promo_style_view_controller.h"
@@ -36,16 +39,21 @@
 @end
 
 @implementation PostRestoreSignInProvider {
+  syncer::SyncUserSettings* _syncUserSettings;
   PromoStyleViewController* _viewController;
   absl::optional<AccountInfo> _accountInfo;
+  bool _historySyncEnabled;
 }
 
 #pragma mark - Initializers
 
-- (instancetype)init {
+- (instancetype)initWithSyncUserSettings:
+    (syncer::SyncUserSettings*)syncUserSettings {
   if (self = [super init]) {
+    _syncUserSettings = syncUserSettings;
     _localState = GetApplicationContext()->GetLocalState();
     _accountInfo = GetPreRestoreIdentity(_localState);
+    _historySyncEnabled = GetPreRestoreHistorySyncEnabled(_localState);
   }
   return self;
 }
@@ -139,6 +147,15 @@
                                 IOSPostRestoreSigninChoice::Continue);
   ClearPreRestoreIdentity(_localState);
 
+  __weak __typeof(self) weakSelf = self;
+  ShowSigninCommandCompletionCallback callback =
+      ^(SigninCoordinatorResult result, SigninCompletionInfo* completionInfo) {
+        if (base::FeatureList::IsEnabled(
+                syncer::kReplaceSyncPromosWithSignInPromos) &&
+            result == SigninCoordinatorResultSuccess) {
+          [weakSelf signinDone];
+        }
+      };
   ShowSigninCommand* command = [[ShowSigninCommand alloc]
       initWithOperation:AuthenticationOperation::kSigninAndSyncReauth
                identity:nil
@@ -146,8 +163,15 @@
                             ACCESS_POINT_POST_DEVICE_RESTORE_SIGNIN_PROMO
             promoAction:signin_metrics::PromoAction::
                             PROMO_ACTION_NO_SIGNIN_PROMO
-               callback:nil];
+               callback:callback];
   [self.handler showSignin:command];
 }
 
+- (void)signinDone {
+  _syncUserSettings->SetSelectedType(syncer::UserSelectableType::kHistory,
+                                     _historySyncEnabled);
+  _syncUserSettings->SetSelectedType(syncer::UserSelectableType::kTabs,
+                                     _historySyncEnabled);
+}
+
 @end
diff --git a/ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider_unittest.mm b/ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider_unittest.mm
index 778d211..6b5d1cdbc 100644
--- a/ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider_unittest.mm
+++ b/ios/chrome/browser/ui/post_restore_signin/post_restore_signin_provider_unittest.mm
@@ -6,12 +6,14 @@
 
 #import "base/test/metrics/histogram_tester.h"
 #import "base/test/scoped_feature_list.h"
+#import "components/sync/test/sync_user_settings_mock.h"
 #import "ios/chrome/browser/promos_manager/constants.h"
 #import "ios/chrome/browser/promos_manager/promo_config.h"
 #import "ios/chrome/browser/shared/public/commands/promos_manager_commands.h"
 #import "ios/chrome/browser/signin/signin_util.h"
 #import "ios/chrome/browser/ui/post_restore_signin/metrics.h"
 #import "ios/chrome/test/ios_chrome_scoped_testing_local_state.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"
@@ -28,7 +30,8 @@
  public:
   explicit PostRestoreSignInProviderTest() {
     SetFakePreRestoreAccountInfo();
-    provider_ = [[PostRestoreSignInProvider alloc] init];
+    provider_ = [[PostRestoreSignInProvider alloc]
+        initWithSyncUserSettings:&sync_user_settings_];
   }
 
   void SetFakePreRestoreAccountInfo() {
@@ -36,15 +39,18 @@
     accountInfo.email = std::string(kFakePreRestoreAccountEmail);
     accountInfo.given_name = std::string(kFakePreRestoreAccountGivenName);
     accountInfo.full_name = std::string(kFakePreRestoreAccountFullName);
-    StorePreRestoreIdentity(local_state_.Get(), accountInfo);
+    StorePreRestoreIdentity(local_state_.Get(), accountInfo,
+                            /*history_sync_enabled=*/false);
   }
 
   void ClearUserName() {
     AccountInfo accountInfo;
     accountInfo.email = std::string(kFakePreRestoreAccountEmail);
-    StorePreRestoreIdentity(local_state_.Get(), accountInfo);
+    StorePreRestoreIdentity(local_state_.Get(), accountInfo,
+                            /*history_sync_enabled=*/false);
     // Reinstantiate a provider so that it picks up the changes.
-    provider_ = [[PostRestoreSignInProvider alloc] init];
+    provider_ = [[PostRestoreSignInProvider alloc]
+        initWithSyncUserSettings:&sync_user_settings_];
   }
 
   void SetupMockHandler() {
@@ -56,6 +62,9 @@
   base::test::ScopedFeatureList scoped_feature_list_;
   id mock_handler_;
   PostRestoreSignInProvider* provider_;
+
+ private:
+  testing::NiceMock<syncer::SyncUserSettingsMock> sync_user_settings_;
 };
 
 // Tests `hasIdentifierAlert` method.
diff --git a/ios/chrome/browser/ui/promos_manager/BUILD.gn b/ios/chrome/browser/ui/promos_manager/BUILD.gn
index 39b78ad9..a516507 100644
--- a/ios/chrome/browser/ui/promos_manager/BUILD.gn
+++ b/ios/chrome/browser/ui/promos_manager/BUILD.gn
@@ -58,6 +58,7 @@
     "//ios/chrome/browser/promos_manager:features",
     "//ios/chrome/browser/promos_manager:types",
     "//ios/chrome/browser/shared/coordinator/chrome_coordinator",
+    "//ios/chrome/browser/sync/model",
     "//ios/public/provider/chrome/browser/signin:choice_api",
     "//third_party/abseil-cpp:absl",
   ]
@@ -67,11 +68,11 @@
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/credential_provider_promo/model:features",
     "//ios/chrome/browser/default_browser/model:utils",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/promos_manager:constants",
     "//ios/chrome/browser/shared/model/application_context",
     "//ios/chrome/browser/shared/model/browser",
     "//ios/chrome/browser/shared/public/commands",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/shared/public/features:system_flags",
     "//ios/chrome/browser/ui/app_store_rating",
     "//ios/chrome/browser/ui/app_store_rating:features",
@@ -106,6 +107,7 @@
     "//ios/chrome/common/ui/confirmation_alert",
     "//ios/chrome/common/ui/promo_style",
     "//ios/chrome/test:test_support",
+    "//ios/web/public/test",
     "//testing/gtest",
     "//third_party/ocmock",
   ]
diff --git a/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.mm b/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.mm
index 1152bbdd..b34b9fb 100644
--- a/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.mm
+++ b/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator.mm
@@ -15,11 +15,11 @@
 #import "base/strings/sys_string_conversions.h"
 #import "components/crash/core/common/crash_key.h"
 #import "components/feature_engagement/public/tracker.h"
+#import "components/sync/service/sync_service.h"
 #import "ios/chrome/app/tests_hook.h"
 #import "ios/chrome/browser/credential_provider_promo/model/features.h"
 #import "ios/chrome/browser/default_browser/model/utils.h"
 #import "ios/chrome/browser/feature_engagement/model/tracker_factory.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/promos_manager/features.h"
 #import "ios/chrome/browser/promos_manager/promo_config.h"
 #import "ios/chrome/browser/promos_manager/promos_manager.h"
@@ -29,7 +29,9 @@
 #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
 #import "ios/chrome/browser/shared/public/commands/credential_provider_promo_commands.h"
 #import "ios/chrome/browser/shared/public/commands/promos_manager_commands.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/public/features/system_flags.h"
+#import "ios/chrome/browser/sync/model/sync_service_factory.h"
 #import "ios/chrome/browser/ui/app_store_rating/app_store_rating_display_handler.h"
 #import "ios/chrome/browser/ui/app_store_rating/features.h"
 #import "ios/chrome/browser/ui/credential_provider_promo/credential_provider_promo_display_handler.h"
@@ -550,8 +552,12 @@
   // TODO(crbug.com/1360880): Create first StandardPromoViewProvider promo.
 
   // StandardPromoAlertProvider promo(s) below:
+  syncer::SyncUserSettings* syncUserSettings =
+      SyncServiceFactory::GetForBrowserState(self.browser->GetBrowserState())
+          ->GetUserSettings();
   _alertProviderPromos[promos_manager::Promo::PostRestoreSignInAlert] =
-      [[PostRestoreSignInProvider alloc] init];
+      [[PostRestoreSignInProvider alloc]
+          initWithSyncUserSettings:syncUserSettings];
   if (GetPostRestoreDefaultBrowserPromoType() ==
       PostRestoreDefaultBrowserPromoType::kAlert) {
     _alertProviderPromos
diff --git a/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator_unittest.mm b/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator_unittest.mm
index 6493b8f..a31a21b 100644
--- a/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator_unittest.mm
+++ b/ios/chrome/browser/ui/promos_manager/promos_manager_coordinator_unittest.mm
@@ -8,7 +8,6 @@
 
 #import "base/apple/foundation_util.h"
 #import "base/test/scoped_feature_list.h"
-#import "base/test/task_environment.h"
 #import "components/prefs/pref_registry_simple.h"
 #import "components/prefs/testing_pref_service.h"
 #import "ios/chrome/browser/promos_manager/features.h"
@@ -16,6 +15,7 @@
 #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h"
 #import "ios/chrome/browser/shared/model/prefs/pref_names.h"
 #import "ios/chrome/browser/shared/public/commands/credential_provider_promo_commands.h"
+#import "ios/chrome/browser/sync/model/sync_service_factory.h"
 #import "ios/chrome/browser/ui/promos_manager/bannered_promo_view_provider.h"
 #import "ios/chrome/browser/ui/promos_manager/promos_manager_coordinator+internal.h"
 #import "ios/chrome/browser/ui/promos_manager/standard_promo_action_handler.h"
@@ -24,6 +24,7 @@
 #import "ios/chrome/common/ui/promo_style/promo_style_view_controller.h"
 #import "ios/chrome/test/ios_chrome_scoped_testing_local_state.h"
 #import "ios/chrome/test/scoped_key_window.h"
+#import "ios/web/public/test/web_task_environment.h"
 #import "testing/gtest/include/gtest/gtest.h"
 #import "testing/platform_test.h"
 #import "third_party/ocmock/OCMock/OCMock.h"
@@ -33,7 +34,10 @@
 class PromosManagerCoordinatorTest : public PlatformTest {
  public:
   void SetUp() override {
-    browser_state_ = TestChromeBrowserState::Builder().Build();
+    TestChromeBrowserState::Builder builder;
+    builder.AddTestingFactory(SyncServiceFactory::GetInstance(),
+                              SyncServiceFactory::GetDefaultFactory());
+    browser_state_ = builder.Build();
     browser_ = std::make_unique<TestBrowser>(browser_state_.get());
     view_controller_ = [[UIViewController alloc] init];
     [scoped_key_window_.Get() setRootViewController:view_controller_];
@@ -52,7 +56,7 @@
   IOSChromeScopedTestingLocalState local_state_;
   base::test::ScopedFeatureList scoped_feature_list_;
   PromosManagerCoordinator* coordinator_;
-  base::test::TaskEnvironment task_environment_;
+  web::WebTaskEnvironment task_environment_;
   std::unique_ptr<TestChromeBrowserState> browser_state_;
   std::unique_ptr<TestBrowser> browser_;
   ScopedKeyWindow scoped_key_window_;
diff --git a/ios/chrome/browser/ui/settings/BUILD.gn b/ios/chrome/browser/ui/settings/BUILD.gn
index 1e5e022c..852addd 100644
--- a/ios/chrome/browser/ui/settings/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/BUILD.gn
@@ -123,7 +123,6 @@
     "//ios/chrome/browser/language/model",
     "//ios/chrome/browser/main",
     "//ios/chrome/browser/net:crurl",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/ntp/home:features",
     "//ios/chrome/browser/passwords/model",
     "//ios/chrome/browser/passwords/model:password_checkup_utils",
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_constants.h b/ios/chrome/browser/ui/settings/autofill/autofill_constants.h
index 741a61fe..e0fc4a7 100644
--- a/ios/chrome/browser/ui/settings/autofill/autofill_constants.h
+++ b/ios/chrome/browser/ui/settings/autofill/autofill_constants.h
@@ -16,6 +16,7 @@
 extern NSString* const kAutofillCreditCardTableViewId;
 extern NSString* const kAutofillCreditCardSwitchViewId;
 extern NSString* const kAutofillCreditCardManagedViewId;
+extern NSString* const kAutofillMandatoryReauthSwitchViewId;
 
 // Accessibility identifier for the edit card table view.
 extern NSString* const kAutofillCreditCardEditTableViewId;
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_constants.mm b/ios/chrome/browser/ui/settings/autofill/autofill_constants.mm
index 68619e6..07f18edc 100644
--- a/ios/chrome/browser/ui/settings/autofill/autofill_constants.mm
+++ b/ios/chrome/browser/ui/settings/autofill/autofill_constants.mm
@@ -19,6 +19,8 @@
     @"kAutofillCreditCardManagedViewId";
 NSString* const kAutofillPaymentMethodsToolbarId =
     @"kAutofillPaymentMethodsToolbarId";
+NSString* const kAutofillMandatoryReauthSwitchViewId =
+    @"kAutofillMandatoryReauthSwitchViewId";
 
 NSString* const kAutofillCreditCardEditTableViewId =
     @"kAutofillCreditCardEditTableViewId";
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller.mm b/ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller.mm
index fe49c4a..9227584 100644
--- a/ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller.mm
@@ -6,9 +6,11 @@
 
 #import "base/apple/foundation_util.h"
 #import "base/check.h"
+#import "base/feature_list.h"
 #import "base/metrics/user_metrics.h"
 #import "base/strings/sys_string_conversions.h"
 #import "components/autofill/core/browser/personal_data_manager.h"
+#import "components/autofill/core/common/autofill_payments_features.h"
 #import "components/autofill/core/common/autofill_prefs.h"
 #import "components/autofill/ios/browser/credit_card_util.h"
 #import "components/autofill/ios/browser/personal_data_manager_observer_bridge.h"
@@ -44,17 +46,20 @@
 
 namespace {
 
-typedef NS_ENUM(NSInteger, SectionIdentifier) {
-  SectionIdentifierSwitches = kSectionIdentifierEnumZero,
+enum SectionIdentifier : NSInteger {
+  SectionIdentifierAutofillCardSwitch = kSectionIdentifierEnumZero,
+  SectionIdentifierMandatoryReauth,
   SectionIdentifierCards,
 };
 
-typedef NS_ENUM(NSInteger, ItemType) {
+enum ItemType : NSInteger {
   ItemTypeAutofillCardSwitch = kItemTypeEnumZero,
   ItemTypeAutofillCardManaged,
   ItemTypeAutofillCardSwitchSubtitle,
   ItemTypeCard,
   ItemTypeHeader,
+  ItemTypeMandatoryReauthSwitch,
+  ItemTypeMandatoryReauthSwitchSubtitle,
 };
 
 }  // namespace
@@ -150,18 +155,27 @@
 
   TableViewModel* model = self.tableViewModel;
 
-  [model addSectionWithIdentifier:SectionIdentifierSwitches];
+  [model addSectionWithIdentifier:SectionIdentifierAutofillCardSwitch];
   if (_browser->GetBrowserState()->GetPrefs()->IsManagedPreference(
           autofill::prefs::kAutofillCreditCardEnabled)) {
     [model addItem:[self cardManagedItem]
-        toSectionWithIdentifier:SectionIdentifierSwitches];
+        toSectionWithIdentifier:SectionIdentifierAutofillCardSwitch];
   } else {
     [model addItem:[self cardSwitchItem]
-        toSectionWithIdentifier:SectionIdentifierSwitches];
+        toSectionWithIdentifier:SectionIdentifierAutofillCardSwitch];
   }
 
   [model setFooter:[self cardSwitchFooter]
-      forSectionWithIdentifier:SectionIdentifierSwitches];
+      forSectionWithIdentifier:SectionIdentifierAutofillCardSwitch];
+
+  if (base::FeatureList::IsEnabled(
+          autofill::features::kAutofillEnablePaymentsMandatoryReauth)) {
+    [model addSectionWithIdentifier:SectionIdentifierMandatoryReauth];
+    [model addItem:[self mandatoryReauthSwitchItem]
+        toSectionWithIdentifier:SectionIdentifierMandatoryReauth];
+    [model setFooter:[self mandatoryReauthSwitchFooter]
+        forSectionWithIdentifier:SectionIdentifierMandatoryReauth];
+  }
 
   [self populateCardSection];
 }
@@ -220,6 +234,25 @@
   return footer;
 }
 
+- (TableViewItem*)mandatoryReauthSwitchItem {
+  TableViewSwitchItem* switchItem =
+      [[TableViewSwitchItem alloc] initWithType:ItemTypeMandatoryReauthSwitch];
+  switchItem.text = l10n_util::GetNSString(
+      IDS_PAYMENTS_AUTOFILL_ENABLE_MANDATORY_REAUTH_TOGGLE_LABEL);
+  switchItem.on = autofill::prefs::IsPaymentMethodsMandatoryReauthEnabled(
+      _browser->GetBrowserState()->GetPrefs());
+  switchItem.accessibilityIdentifier = kAutofillMandatoryReauthSwitchViewId;
+  return switchItem;
+}
+
+- (TableViewHeaderFooterItem*)mandatoryReauthSwitchFooter {
+  TableViewLinkHeaderFooterItem* footer = [[TableViewLinkHeaderFooterItem alloc]
+      initWithType:ItemTypeMandatoryReauthSwitchSubtitle];
+  footer.text = l10n_util::GetNSString(
+      IDS_PAYMENTS_AUTOFILL_ENABLE_MANDATORY_REAUTH_TOGGLE_SUBLABEL);
+  return footer;
+}
+
 - (TableViewHeaderFooterItem*)cardSectionHeader {
   TableViewTextHeaderFooterItem* header =
       [[TableViewTextHeaderFooterItem alloc] initWithType:ItemTypeHeader];
@@ -351,6 +384,10 @@
     case ItemTypeAutofillCardSwitchSubtitle:
     case ItemTypeCard:
     case ItemTypeHeader:
+    case ItemTypeMandatoryReauthSwitchSubtitle:
+    case ItemTypeMandatoryReauthSwitch:
+      // TODO(b/297268822): Wire up callback functions to handle mandatory
+      // reauth switch toggle events
       break;
     case ItemTypeAutofillCardSwitch: {
       TableViewSwitchCell* switchCell =
@@ -385,11 +422,11 @@
 #pragma mark - Switch Helpers
 
 // Sets switchItem's state to `on`. It is important that there is only one item
-// of `switchItemType` in SectionIdentifierSwitches.
+// of `switchItemType` in SectionIdentifierAutofillCardSwitch.
 - (void)setSwitchItemOn:(BOOL)on itemType:(ItemType)switchItemType {
-  NSIndexPath* switchPath =
-      [self.tableViewModel indexPathForItemType:switchItemType
-                              sectionIdentifier:SectionIdentifierSwitches];
+  NSIndexPath* switchPath = [self.tableViewModel
+      indexPathForItemType:switchItemType
+         sectionIdentifier:SectionIdentifierAutofillCardSwitch];
   TableViewSwitchItem* switchItem =
       base::apple::ObjCCastStrict<TableViewSwitchItem>(
           [self.tableViewModel itemAtIndexPath:switchPath]);
@@ -398,17 +435,17 @@
 
 // Sets switchItem's enabled status to `enabled` and reconfigures the
 // corresponding cell. It is important that there is no more than one item of
-// `switchItemType` in SectionIdentifierSwitches.
+// `switchItemType` in SectionIdentifierAutofillCardSwitch.
 - (void)setSwitchItemEnabled:(BOOL)enabled itemType:(ItemType)switchItemType {
   TableViewModel* model = self.tableViewModel;
 
   if (![model hasItemForItemType:switchItemType
-               sectionIdentifier:SectionIdentifierSwitches]) {
+               sectionIdentifier:SectionIdentifierAutofillCardSwitch]) {
     return;
   }
   NSIndexPath* switchPath =
       [model indexPathForItemType:switchItemType
-                sectionIdentifier:SectionIdentifierSwitches];
+                sectionIdentifier:SectionIdentifierAutofillCardSwitch];
   TableViewSwitchItem* switchItem =
       base::apple::ObjCCastStrict<TableViewSwitchItem>(
           [model itemAtIndexPath:switchPath]);
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller_unittest.mm
index 48d585a..f380281 100644
--- a/ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller_unittest.mm
@@ -7,10 +7,13 @@
 #import "base/apple/foundation_util.h"
 #import "base/strings/utf_string_conversions.h"
 #import "base/test/ios/wait_util.h"
+#import "base/test/scoped_feature_list.h"
 #import "base/uuid.h"
 #import "components/autofill/core/browser/data_model/credit_card.h"
 #import "components/autofill/core/browser/personal_data_manager.h"
 #import "components/autofill/core/common/autofill_features.h"
+#import "components/autofill/core/common/autofill_payments_features.h"
+#import "components/strings/grit/components_strings.h"
 #import "ios/chrome/browser/autofill/personal_data_manager_factory.h"
 #import "ios/chrome/browser/shared/model/browser/test/test_browser.h"
 #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h"
@@ -20,6 +23,7 @@
 #import "ios/chrome/test/ios_chrome_scoped_testing_local_state.h"
 #import "ios/web/public/test/web_task_environment.h"
 #import "testing/gtest/include/gtest/gtest.h"
+#import "ui/base/l10n/l10n_util.h"
 
 namespace {
 
@@ -134,4 +138,33 @@
   }));
 }
 
+// Tests that when the MandatoryReauth feature is enabled a switch
+// appears
+TEST_F(AutofillCreditCardTableViewControllerTest,
+       TestMandatoryReauthSwitchExists) {
+  base::test::ScopedFeatureList feature_list_{
+      autofill::features::kAutofillEnablePaymentsMandatoryReauth};
+  CreateController();
+  CheckController();
+
+  // Expect 2 sections, 1 for switches and 1 for mandatory reauth.
+  EXPECT_EQ(2, NumberOfSections());
+
+  // Expect Mandatory Reauth section to have 2 items, the switch and the
+  // subtitle.
+  EXPECT_EQ(1, NumberOfItemsInSection(1));
+
+  // Confirm the text to the side of the switch.
+  CheckSwitchCellStateAndText(
+      true,
+      l10n_util::GetNSString(
+          IDS_PAYMENTS_AUTOFILL_ENABLE_MANDATORY_REAUTH_TOGGLE_LABEL),
+      1, 0);
+
+  // Confirm the sublabel of the switch.
+  CheckSectionFooter(
+      l10n_util::GetNSString(
+          IDS_PAYMENTS_AUTOFILL_ENABLE_MANDATORY_REAUTH_TOGGLE_SUBLABEL),
+      1);
+}
 }  // namespace
diff --git a/ios/chrome/browser/ui/settings/password/password_sharing/family_promo_coordinator.mm b/ios/chrome/browser/ui/settings/password/password_sharing/family_promo_coordinator.mm
index 42fa37f85..11079d3 100644
--- a/ios/chrome/browser/ui/settings/password/password_sharing/family_promo_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/password/password_sharing/family_promo_coordinator.mm
@@ -71,9 +71,21 @@
   id<ApplicationCommands> handler = HandlerForProtocol(
       self.browser->GetCommandDispatcher(), ApplicationCommands);
   OpenNewTabCommand* command =
-      [OpenNewTabCommand commandWithURLFromChrome:GURL(kFamilyGroupSiteURL)];
+      [OpenNewTabCommand commandWithURLFromChrome:[self familyManagementURL]];
   [handler closeSettingsUIAndOpenURL:command];
   [self.delegate familyPromoCoordinatorWasDismissed:self];
 }
 
+#pragma mark - Private
+
+// Returns family management url based on the `_familyPromoType`.
+- (GURL)familyManagementURL {
+  switch (_familyPromoType) {
+    case FamilyPromoType::kUserNotInFamilyGroup:
+      return GURL(kCreateFamilyGroupURL);
+    case FamilyPromoType::kUserWithNoOtherFamilyMembers:
+      return GURL(kManageFamilyGroupURL);
+  }
+}
+
 @end
diff --git a/ios/chrome/browser/ui/settings/password/password_sharing/password_sharing_constants.h b/ios/chrome/browser/ui/settings/password/password_sharing/password_sharing_constants.h
index 670dd6d..64fe1ec 100644
--- a/ios/chrome/browser/ui/settings/password/password_sharing/password_sharing_constants.h
+++ b/ios/chrome/browser/ui/settings/password/password_sharing/password_sharing_constants.h
@@ -21,8 +21,9 @@
 // The accessibility identifier of the sharing status view.
 extern NSString* const kSharingStatusDoneButtonId;
 
-// Link for creating family group with Google Families.
-extern const char kFamilyGroupSiteURL[];
+// Links for managing Google Family groups.
+extern const char kCreateFamilyGroupURL[];
+extern const char kManageFamilyGroupURL[];
 
 // Link for the password sharing HC article.
 extern const char kPasswordSharingLearnMoreURL[];
diff --git a/ios/chrome/browser/ui/settings/password/password_sharing/password_sharing_constants.mm b/ios/chrome/browser/ui/settings/password/password_sharing/password_sharing_constants.mm
index 27b9ca0..6465568 100644
--- a/ios/chrome/browser/ui/settings/password/password_sharing/password_sharing_constants.mm
+++ b/ios/chrome/browser/ui/settings/password/password_sharing/password_sharing_constants.mm
@@ -15,7 +15,10 @@
 
 NSString* const kSharingStatusDoneButtonId = @"SharingStatusDoneButtonId";
 
-const char kFamilyGroupSiteURL[] = "https://families.google.com/families/";
+const char kCreateFamilyGroupURL[] =
+    "https://myaccount.google.com/family/create?utm_source=cpwd";
+const char kManageFamilyGroupURL[] =
+    "https://myaccount.google.com/family/details?utm_source=cpwd";
 
 const char kPasswordSharingLearnMoreURL[] =
     "https://support.google.com/chrome/?p=password_sharing";
diff --git a/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator_unittest.mm b/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator_unittest.mm
index 56ea15b..44b353c 100644
--- a/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator_unittest.mm
@@ -30,7 +30,6 @@
 #import "components/strings/grit/components_strings.h"
 #import "components/sync/test/mock_sync_service.h"
 #import "components/sync_preferences/pref_service_mock_factory.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/passwords/model/ios_chrome_affiliation_service_factory.h"
 #import "ios/chrome/browser/passwords/model/ios_chrome_password_check_manager.h"
 #import "ios/chrome/browser/passwords/model/ios_chrome_password_check_manager_factory.h"
diff --git a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
index 66b0aff9..f626d1b 100644
--- a/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/settings_table_view_controller.mm
@@ -42,8 +42,6 @@
 #import "ios/chrome/browser/feature_engagement/model/tracker_factory.h"
 #import "ios/chrome/browser/language/model/language_model_manager_factory.h"
 #import "ios/chrome/browser/net/crurl.h"
-#import "ios/chrome/browser/ntp/features.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/passwords/model/ios_chrome_password_check_manager.h"
 #import "ios/chrome/browser/passwords/model/ios_chrome_password_check_manager_factory.h"
 #import "ios/chrome/browser/passwords/model/password_check_observer_bridge.h"
diff --git a/ios/chrome/browser/ui/start_surface/BUILD.gn b/ios/chrome/browser/ui/start_surface/BUILD.gn
index 0f8eee9..87cd5d54 100644
--- a/ios/chrome/browser/ui/start_surface/BUILD.gn
+++ b/ios/chrome/browser/ui/start_surface/BUILD.gn
@@ -92,6 +92,7 @@
     ":feature_flags",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/ntp/home:features",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/ui/content_suggestions:constants",
     "//ios/chrome/browser/ui/content_suggestions/tab_resumption:constants",
     "//ios/chrome/test/earl_grey:eg_test_support+eg2",
diff --git a/ios/chrome/browser/ui/start_surface/start_surface_egtest.mm b/ios/chrome/browser/ui/start_surface/start_surface_egtest.mm
index a9ac5c2f..14a8f5b 100644
--- a/ios/chrome/browser/ui/start_surface/start_surface_egtest.mm
+++ b/ios/chrome/browser/ui/start_surface/start_surface_egtest.mm
@@ -6,7 +6,7 @@
 
 #import "base/test/ios/wait_util.h"
 #import "base/time/time.h"
-#import "ios/chrome/browser/ntp/home/features.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h"
 #import "ios/chrome/browser/ui/content_suggestions/tab_resumption/tab_resumption_constants.h"
 #import "ios/chrome/browser/ui/start_surface/start_surface_features.h"
diff --git a/ios/chrome/browser/ui/tabs/tab_pickup/BUILD.gn b/ios/chrome/browser/ui/tabs/tab_pickup/BUILD.gn
index 44afa55..cd2706f7 100644
--- a/ios/chrome/browser/ui/tabs/tab_pickup/BUILD.gn
+++ b/ios/chrome/browser/ui/tabs/tab_pickup/BUILD.gn
@@ -11,6 +11,7 @@
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/ntp/home:features",
     "//ios/chrome/browser/shared/model/prefs:pref_names",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/signin:fake_system_identity",
     "//ios/chrome/browser/tabs/model/tab_pickup:features",
     "//ios/chrome/browser/ui/authentication:eg_test_support+eg2",
diff --git a/ios/chrome/browser/ui/tabs/tab_pickup/tab_pickup_egtest.mm b/ios/chrome/browser/ui/tabs/tab_pickup/tab_pickup_egtest.mm
index 9b53e4d..886e6d7 100644
--- a/ios/chrome/browser/ui/tabs/tab_pickup/tab_pickup_egtest.mm
+++ b/ios/chrome/browser/ui/tabs/tab_pickup/tab_pickup_egtest.mm
@@ -4,8 +4,8 @@
 
 #import "base/strings/sys_string_conversions.h"
 #import "base/test/ios/wait_util.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/shared/model/prefs/pref_names.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/signin/fake_system_identity.h"
 #import "ios/chrome/browser/tabs/model/tab_pickup/features.h"
 #import "ios/chrome/browser/ui/authentication/signin_earl_grey.h"
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
index 37a555c..2e51db3 100644
--- a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
+++ b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
@@ -25,7 +25,6 @@
 #import "ios/chrome/browser/drag_and_drop/model/drag_item_util.h"
 #import "ios/chrome/browser/drag_and_drop/model/url_drag_drop_handler.h"
 #import "ios/chrome/browser/feature_engagement/model/tracker_factory.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/ntp/new_tab_page_util.h"
 #import "ios/chrome/browser/shared/coordinator/scene/scene_state.h"
 #import "ios/chrome/browser/shared/coordinator/scene/scene_state_browser_agent.h"
diff --git a/ios/chrome/browser/ui/tabs/tab_view.mm b/ios/chrome/browser/ui/tabs/tab_view.mm
index 527ca28..fce076ab 100644
--- a/ios/chrome/browser/ui/tabs/tab_view.mm
+++ b/ios/chrome/browser/ui/tabs/tab_view.mm
@@ -9,7 +9,6 @@
 #import "base/i18n/rtl.h"
 #import "base/ios/ios_util.h"
 #import "base/strings/sys_string_conversions.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/public/features/system_flags.h"
 #import "ios/chrome/browser/shared/ui/elements/fade_truncating_label.h"
diff --git a/ios/chrome/browser/ui/toolbar/BUILD.gn b/ios/chrome/browser/ui/toolbar/BUILD.gn
index 6214e2f17..bd8e05ef 100644
--- a/ios/chrome/browser/ui/toolbar/BUILD.gn
+++ b/ios/chrome/browser/ui/toolbar/BUILD.gn
@@ -42,7 +42,6 @@
     "//ios/chrome/browser/first_run",
     "//ios/chrome/browser/main",
     "//ios/chrome/browser/ntp",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/ntp:util",
     "//ios/chrome/browser/overlays",
     "//ios/chrome/browser/policy:policy_util",
diff --git a/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.mm
index 95abf5b..10f8dd6 100644
--- a/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.mm
+++ b/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.mm
@@ -11,7 +11,6 @@
 #import "base/metrics/field_trial_params.h"
 #import "base/metrics/user_metrics.h"
 #import "base/metrics/user_metrics_action.h"
-#import "ios/chrome/browser/ntp/home/features.h"
 #import "ios/chrome/browser/shared/public/commands/omnibox_commands.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/ui/util/dynamic_type_util.h"
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_coordinator.mm b/ios/chrome/browser/ui/toolbar/toolbar_coordinator.mm
index 56fcc5e..d0a96b3 100644
--- a/ios/chrome/browser/ui/toolbar/toolbar_coordinator.mm
+++ b/ios/chrome/browser/ui/toolbar/toolbar_coordinator.mm
@@ -6,7 +6,6 @@
 
 #import "base/apple/foundation_util.h"
 #import "components/prefs/pref_service.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h"
 #import "ios/chrome/browser/ntp/new_tab_page_util.h"
 #import "ios/chrome/browser/overlays/public/overlay_presentation_context.h"
diff --git a/ios/chrome/browser/web/browser_about_rewriter.cc b/ios/chrome/browser/web/browser_about_rewriter.cc
index d53e0eda..7671a708 100644
--- a/ios/chrome/browser/web/browser_about_rewriter.cc
+++ b/ios/chrome/browser/web/browser_about_rewriter.cc
@@ -10,7 +10,6 @@
 #include "base/feature_list.h"
 #include "components/url_formatter/url_fixer.h"
 #include "ios/chrome/browser/shared/model/url/chrome_url_constants.h"
-#include "ios/chrome/browser/shared/public/features/features.h"
 #include "ios/components/webui/web_ui_url_constants.h"
 #include "url/url_constants.h"
 
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn
index 703a49a..c8f290a6 100644
--- a/ios/chrome/test/BUILD.gn
+++ b/ios/chrome/test/BUILD.gn
@@ -225,6 +225,7 @@
     "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/autofill_address_profile:unit_tests",
     "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common:unit_tests",
     "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/confirm:unit_tests",
+    "//ios/chrome/browser/intents:unit_tests",
     "//ios/chrome/browser/itunes_urls/model:unit_tests",
     "//ios/chrome/browser/json_parser:unit_tests",
     "//ios/chrome/browser/language/model:unit_tests",
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn
index fa06b90..56e7d83f 100644
--- a/ios/chrome/test/earl_grey/BUILD.gn
+++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -90,7 +90,6 @@
     "//ios/chrome/browser/first_run",
     "//ios/chrome/browser/https_upgrades/model:eg_app_support+eg2",
     "//ios/chrome/browser/metrics:eg_app_support+eg2",
-    "//ios/chrome/browser/ntp:features",
     "//ios/chrome/browser/optimization_guide:eg_app_support+eg2",
     "//ios/chrome/browser/passwords/model",
     "//ios/chrome/browser/passwords/model:eg_app_support+eg2",
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm
index fd93695..0c895682 100644
--- a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm
+++ b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm
@@ -39,7 +39,6 @@
 #import "ios/chrome/browser/default_browser/model/utils.h"
 #import "ios/chrome/browser/default_browser/model/utils_test_support.h"
 #import "ios/chrome/browser/first_run/first_run.h"
-#import "ios/chrome/browser/ntp/features.h"
 #import "ios/chrome/browser/search_engines/model/search_engines_util.h"
 #import "ios/chrome/browser/search_engines/model/template_url_service_factory.h"
 #import "ios/chrome/browser/sessions/session_restoration_util.h"
diff --git a/ios/web_view/internal/signin/ios_web_view_signin_client.h b/ios/web_view/internal/signin/ios_web_view_signin_client.h
index 635e2b2..b5e32bc 100644
--- a/ios/web_view/internal/signin/ios_web_view_signin_client.h
+++ b/ios/web_view/internal/signin/ios_web_view_signin_client.h
@@ -55,6 +55,10 @@
       GaiaAuthConsumer* consumer,
       gaia::GaiaSource source) override;
   version_info::Channel GetClientChannel() override;
+  void OnPrimaryAccountChangedWithEventSource(
+      signin::PrimaryAccountChangeEvent event_details,
+      absl::variant<signin_metrics::AccessPoint, signin_metrics::ProfileSignout>
+          event_source) override;
 
  private:
   // Helper to delay callbacks until connection becomes online again.
diff --git a/ios/web_view/internal/signin/ios_web_view_signin_client.mm b/ios/web_view/internal/signin/ios_web_view_signin_client.mm
index 167af98..90ec64c 100644
--- a/ios/web_view/internal/signin/ios_web_view_signin_client.mm
+++ b/ios/web_view/internal/signin/ios_web_view_signin_client.mm
@@ -6,6 +6,7 @@
 
 #import "components/signin/core/browser/cookie_settings_util.h"
 #import "components/signin/ios/browser/wait_for_network_callback_helper_ios.h"
+#import "components/signin/public/identity_manager/primary_account_change_event.h"
 #import "components/version_info/channel.h"
 #import "ios/web_view/internal/signin/web_view_gaia_auth_fetcher.h"
 #import "ios/web_view/internal/web_view_browser_state.h"
@@ -86,3 +87,8 @@
   // implemented.
   return version_info::Channel::STABLE;
 }
+
+void IOSWebViewSigninClient::OnPrimaryAccountChangedWithEventSource(
+    signin::PrimaryAccountChangeEvent event_details,
+    absl::variant<signin_metrics::AccessPoint, signin_metrics::ProfileSignout>
+        event_source) {}
diff --git a/ios_internal b/ios_internal
index 1be9791..f9a83e8 160000
--- a/ios_internal
+++ b/ios_internal
@@ -1 +1 @@
-Subproject commit 1be9791237c4cd9def25d4b0276868f05aae5ba6
+Subproject commit f9a83e85a8584ef7fc1bc0ecdfb5c0e5e4468242
diff --git a/media/audio/audio_features.cc b/media/audio/audio_features.cc
index 0c134ca..fb4127508 100644
--- a/media/audio/audio_features.cc
+++ b/media/audio/audio_features.cc
@@ -26,7 +26,7 @@
 // for audio input streams.
 BASE_FEATURE(kUseAAudioInput,
              "UseAAudioInput",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 #endif
 
 #if BUILDFLAG(IS_WIN)
diff --git a/media/base/supported_types.cc b/media/base/supported_types.cc
index e87266e..bf50544 100644
--- a/media/base/supported_types.cc
+++ b/media/base/supported_types.cc
@@ -296,8 +296,8 @@
 }
 
 bool IsMPEG4Supported() {
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  return true;
+#if BUILDFLAG(IS_CHROMEOS) && BUILDFLAG(USE_PROPRIETARY_CODECS)
+  return base::FeatureList::IsEnabled(kCrOSLegacyMediaFormats);
 #else
   return false;
 #endif
@@ -355,9 +355,10 @@
 #endif
 
   switch (type.codec) {
+    case VideoCodec::kTheora:
+      return IsBuiltInVideoCodec(type.codec);
     case VideoCodec::kH264:
     case VideoCodec::kVP8:
-    case VideoCodec::kTheora:
       return true;
     case VideoCodec::kAV1:
       return IsAV1Supported(type);
@@ -427,7 +428,7 @@
 bool IsBuiltInVideoCodec(VideoCodec codec) {
 #if BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
   if (codec == VideoCodec::kTheora)
-    return true;
+    return base::FeatureList::IsEnabled(kTheoraVideoCodec);
   if (codec == VideoCodec::kVP8)
     return true;
 #if BUILDFLAG(USE_PROPRIETARY_CODECS)
diff --git a/media/base/supported_types_unittest.cc b/media/base/supported_types_unittest.cc
index 611d754..f3862f2 100644
--- a/media/base/supported_types_unittest.cc
+++ b/media/base/supported_types_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "media/base/media_switches.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 #if BUILDFLAG(IS_ANDROID)
@@ -24,11 +25,21 @@
 const bool kPropCodecsEnabled = false;
 #endif
 
-#if BUILDFLAG(IS_CHROMEOS_ASH) && BUILDFLAG(USE_PROPRIETARY_CODECS)
-const bool kMpeg4Supported = true;
+bool IsTheoraSupported() {
+#if BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
+  return base::FeatureList::IsEnabled(kTheoraVideoCodec);
 #else
-const bool kMpeg4Supported = false;
+  return false;
 #endif
+}
+
+bool IsMPEG4Supported() {
+#if BUILDFLAG(IS_CHROMEOS) && BUILDFLAG(USE_PROPRIETARY_CODECS)
+  return base::FeatureList::IsEnabled(kCrOSLegacyMediaFormats);
+#else
+  return false;
+#endif
+}
 
 TEST(SupportedTypesTest, IsSupportedVideoTypeBasics) {
   // Default to common 709.
@@ -42,7 +53,8 @@
       {VideoCodec::kVP8, VP8PROFILE_ANY, kUnspecifiedLevel, kColorSpace}));
   EXPECT_TRUE(IsSupportedVideoType(
       {VideoCodec::kVP9, VP9PROFILE_PROFILE0, kUnspecifiedLevel, kColorSpace}));
-  EXPECT_TRUE(
+  EXPECT_EQ(
+      IsTheoraSupported(),
       IsSupportedVideoType({VideoCodec::kTheora, VIDEO_CODEC_PROFILE_UNKNOWN,
                             kUnspecifiedLevel, kColorSpace}));
 
@@ -62,7 +74,7 @@
             IsSupportedVideoType(
                 {VideoCodec::kH264, H264PROFILE_BASELINE, 1, kColorSpace}));
   EXPECT_EQ(
-      kMpeg4Supported,
+      IsMPEG4Supported(),
       IsSupportedVideoType({VideoCodec::kMPEG4, VIDEO_CODEC_PROFILE_UNKNOWN,
                             kUnspecifiedLevel, kColorSpace}));
 
@@ -292,7 +304,8 @@
       {VideoCodec::kVP8, VP8PROFILE_ANY, kUnspecifiedLevel, color_space}));
   EXPECT_TRUE(IsSupportedVideoType(
       {VideoCodec::kVP9, VP9PROFILE_PROFILE0, kUnspecifiedLevel, color_space}));
-  EXPECT_TRUE(
+  EXPECT_EQ(
+      IsTheoraSupported(),
       IsSupportedVideoType({VideoCodec::kTheora, VIDEO_CODEC_PROFILE_UNKNOWN,
                             kUnspecifiedLevel, color_space}));
 
@@ -309,7 +322,8 @@
       {VideoCodec::kVP8, VP8PROFILE_ANY, kUnspecifiedLevel, color_space}));
   EXPECT_TRUE(IsSupportedVideoType(
       {VideoCodec::kVP9, VP9PROFILE_PROFILE0, kUnspecifiedLevel, color_space}));
-  EXPECT_TRUE(
+  EXPECT_EQ(
+      IsTheoraSupported(),
       IsSupportedVideoType({VideoCodec::kTheora, VIDEO_CODEC_PROFILE_UNKNOWN,
                             kUnspecifiedLevel, color_space}));
   EXPECT_TRUE(
@@ -322,7 +336,8 @@
       {VideoCodec::kVP8, VP8PROFILE_ANY, kUnspecifiedLevel, color_space}));
   EXPECT_TRUE(IsSupportedVideoType(
       {VideoCodec::kVP9, VP9PROFILE_PROFILE0, kUnspecifiedLevel, color_space}));
-  EXPECT_TRUE(
+  EXPECT_EQ(
+      IsTheoraSupported(),
       IsSupportedVideoType({VideoCodec::kTheora, VIDEO_CODEC_PROFILE_UNKNOWN,
                             kUnspecifiedLevel, color_space}));
   // HDR metadata only works with the PQ transfer.
@@ -349,7 +364,7 @@
         // BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
 
 #if BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
-  EXPECT_TRUE(IsBuiltInVideoCodec(VideoCodec::kTheora));
+  EXPECT_EQ(IsTheoraSupported(), IsBuiltInVideoCodec(VideoCodec::kTheora));
 #else
   EXPECT_FALSE(IsBuiltInVideoCodec(VideoCodec::kTheora));
 #endif  // BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
diff --git a/media/capture/video/chromeos/mojom/BUILD.gn b/media/capture/video/chromeos/mojom/BUILD.gn
index ac1eccc..e674bb1 100644
--- a/media/capture/video/chromeos/mojom/BUILD.gn
+++ b/media/capture/video/chromeos/mojom/BUILD.gn
@@ -38,7 +38,11 @@
     "//components/chromeos_camera/common",
     "//media/capture/mojom:image_capture",
   ]
-  public_deps = [ ":cros_camera_common" ]
+
+  public_deps = [
+    ":cros_camera_common",
+    "//mojo/public/mojom/base",
+  ]
 }
 
 mojom("jpeg_accelerator") {
diff --git a/media/capture/video/chromeos/mojom/camera_features.mojom b/media/capture/video/chromeos/mojom/camera_features.mojom
index 68f2f0c..a7a0ad9d 100644
--- a/media/capture/video/chromeos/mojom/camera_features.mojom
+++ b/media/capture/video/chromeos/mojom/camera_features.mojom
@@ -21,3 +21,12 @@
   // Turns on/off face distortion correction.
   bool enable_rectiface;
 };
+
+// The status of Portrait Mode segmentation result.
+enum PortraitModeSegResult {
+  kSuccess = 0,   // Portrait mode segmentation succeeds.
+  kFailure = 1,   // Portrait mode segmentation fails.
+  kTimeout = 2,   // Portrait processing timeout.
+  kNoFaces = 3,   // Portrait mode segmentation fails with no face detected.
+  kUnknown = 4,   // Portrait mode segmentation fails with unknown reason.
+};
diff --git a/mojo/public/tools/mojom/mojom/generate/translate.py b/mojo/public/tools/mojom/mojom/generate/translate.py
index 1794e00..83bb297 100644
--- a/mojo/public/tools/mojom/mojom/generate/translate.py
+++ b/mojo/public/tools/mojom/mojom/generate/translate.py
@@ -176,7 +176,6 @@
     'x:ash.ime.mojom.PersonalizationMode',
     'x:ash.language.mojom.FeatureId',
     'x:blink.mojom.ScrollRestorationType',
-    'x:chrome_cleaner.mojom.PromptAcceptance',
     'x:chromeos.cdm.mojom.CdmKeyStatus',
     'x:chromeos.cdm.mojom.CdmMessageType',
     'x:chromeos.cdm.mojom.CdmSessionType',
diff --git a/net/base/address_map_linux.h b/net/base/address_map_linux.h
index 1ee7b7b..e57fe88 100644
--- a/net/base/address_map_linux.h
+++ b/net/base/address_map_linux.h
@@ -6,13 +6,13 @@
 #define NET_BASE_ADDRESS_MAP_LINUX_H_
 
 #include <map>
+#include <optional>
 #include <unordered_set>
 
 #include "base/containers/flat_map.h"
 #include "base/functional/callback_forward.h"
 #include "net/base/ip_address.h"
 #include "net/base/net_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 struct ifaddrmsg;
 
@@ -35,10 +35,10 @@
   using AddressMap = std::map<IPAddress, struct ifaddrmsg>;
 
   // Represents a diff between one AddressMap and a new one. IPAddresses that
-  // map to absl::nullopt have been deleted from the map, and IPAddresses that
+  // map to std::nullopt have been deleted from the map, and IPAddresses that
   // map to non-nullopt have been added or updated.
   using AddressMapDiff =
-      base::flat_map<IPAddress, absl::optional<struct ifaddrmsg>>;
+      base::flat_map<IPAddress, std::optional<struct ifaddrmsg>>;
   // Represents a diff between one set of online links and new one. Interface
   // indices that map to true are newly online and indices that map to false are
   // newly offline.
diff --git a/net/base/address_tracker_linux.cc b/net/base/address_tracker_linux.cc
index b9c8f8e..1a18bc4 100644
--- a/net/base/address_tracker_linux.cc
+++ b/net/base/address_tracker_linux.cc
@@ -8,8 +8,10 @@
 #include <linux/if.h>
 #include <stdint.h>
 #include <sys/ioctl.h>
-#include <vector>
+
+#include <optional>
 #include <utility>
+#include <vector>
 
 #include "base/check.h"
 #include "base/dcheck_is_on.h"
@@ -25,7 +27,6 @@
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
 #include "net/base/network_interfaces_linux.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_ANDROID)
 #include "base/android/build_info.h"
@@ -419,7 +420,7 @@
       std::max(base::GetPageSize(), kMinNetlinkBufferSize));
 
   {
-    absl::optional<base::ScopedBlockingCall> blocking_call;
+    std::optional<base::ScopedBlockingCall> blocking_call;
     if (tracking_) {
       // If the loop below takes a long time to run, a new thread should added
       // to the current thread pool to ensure forward progress of all tasks.
@@ -524,7 +525,7 @@
           if (address_map_.erase(address)) {
             *address_changed = true;
             if (address_map_diff_.has_value()) {
-              (*address_map_diff_)[address] = absl::nullopt;
+              (*address_map_diff_)[address] = std::nullopt;
             }
           }
         }
diff --git a/net/base/address_tracker_linux.h b/net/base/address_tracker_linux.h
index b668973..181a7dc 100644
--- a/net/base/address_tracker_linux.h
+++ b/net/base/address_tracker_linux.h
@@ -257,12 +257,12 @@
 
   mutable base::Lock address_map_lock_;
   AddressMap address_map_ GUARDED_BY(address_map_lock_);
-  absl::optional<AddressMapDiff> address_map_diff_;
+  std::optional<AddressMapDiff> address_map_diff_;
 
   // Set of interface indices for links that are currently online.
   mutable base::Lock online_links_lock_ ACQUIRED_AFTER(address_map_lock_);
   std::unordered_set<int> online_links_ GUARDED_BY(online_links_lock_);
-  absl::optional<OnlineLinksDiff> online_links_diff_;
+  std::optional<OnlineLinksDiff> online_links_diff_;
 
   // Set of interface names that should be ignored.
   const std::unordered_set<std::string> ignored_interfaces_;
diff --git a/net/base/address_tracker_linux_unittest.cc b/net/base/address_tracker_linux_unittest.cc
index 6767735..4774334c2 100644
--- a/net/base/address_tracker_linux_unittest.cc
+++ b/net/base/address_tracker_linux_unittest.cc
@@ -741,7 +741,7 @@
 };
 
 base::File GetSwitchValueFile(const base::CommandLine* command_line,
-                              base::StringPiece name) {
+                              std::string_view name) {
   std::string value = command_line->GetSwitchValueASCII(name);
   int fd;
   CHECK(base::StringToInt(value, &fd));
diff --git a/net/base/backoff_entry_serializer_fuzzer.cc b/net/base/backoff_entry_serializer_fuzzer.cc
index 8930b2a..1039604 100644
--- a/net/base/backoff_entry_serializer_fuzzer.cc
+++ b/net/base/backoff_entry_serializer_fuzzer.cc
@@ -6,6 +6,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 
 #include "base/json/json_reader.h"
 #include "base/logging.h"
@@ -17,7 +18,6 @@
 #include "net/base/backoff_entry_serializer_fuzzer_input.pb.h"
 #include "testing/libfuzzer/proto/json_proto_converter.h"
 #include "testing/libfuzzer/proto/lpm_interface.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -46,10 +46,10 @@
   base::TimeTicks now_ticks() const {
     return base::TimeTicks() + base::Microseconds(input_->now_ticks());
   }
-  absl::optional<base::Value> serialized_entry() const {
+  std::optional<base::Value> serialized_entry() const {
     json_proto::JsonProtoConverter converter;
     std::string json_array = converter.Convert(input_->serialized_entry());
-    absl::optional<base::Value> value = base::JSONReader::Read(json_array);
+    std::optional<base::Value> value = base::JSONReader::Read(json_array);
     return value;
   }
 
@@ -87,7 +87,7 @@
 // we check that the parsed BackoffEntry values are equivalent.
 void TestDeserialize(const ProtoTranslator& translator) {
   // Attempt to convert the json_proto.ArrayValue to a base::Value.
-  absl::optional<base::Value> value = translator.serialized_entry();
+  std::optional<base::Value> value = translator.serialized_entry();
   if (!value)
     return;
   DCHECK(value->is_list());
diff --git a/net/base/connection_endpoint_metadata.cc b/net/base/connection_endpoint_metadata.cc
index e9a19473..6e4f857 100644
--- a/net/base/connection_endpoint_metadata.cc
+++ b/net/base/connection_endpoint_metadata.cc
@@ -4,13 +4,13 @@
 
 #include "net/base/connection_endpoint_metadata.h"
 
+#include <optional>
 #include <string>
 #include <utility>
 #include <vector>
 
 #include "base/base64.h"
 #include "base/values.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -55,11 +55,11 @@
 }
 
 // static
-absl::optional<ConnectionEndpointMetadata>
-ConnectionEndpointMetadata::FromValue(const base::Value& value) {
+std::optional<ConnectionEndpointMetadata> ConnectionEndpointMetadata::FromValue(
+    const base::Value& value) {
   const base::Value::Dict* dict = value.GetIfDict();
   if (!dict)
-    return absl::nullopt;
+    return std::nullopt;
 
   const base::Value::List* alpns_list =
       dict->FindList(kSupportedProtocolAlpnsKey);
@@ -68,21 +68,21 @@
   const std::string* target_name_value = dict->FindString(kTargetNameKey);
 
   if (!alpns_list || !ech_config_list_value)
-    return absl::nullopt;
+    return std::nullopt;
 
   ConnectionEndpointMetadata metadata;
 
   std::vector<std::string> alpns;
   for (const base::Value& alpn : *alpns_list) {
     if (!alpn.is_string())
-      return absl::nullopt;
+      return std::nullopt;
     metadata.supported_protocol_alpns.push_back(alpn.GetString());
   }
 
-  absl::optional<std::vector<uint8_t>> decoded =
+  std::optional<std::vector<uint8_t>> decoded =
       base::Base64Decode(*ech_config_list_value);
   if (!decoded)
-    return absl::nullopt;
+    return std::nullopt;
   metadata.ech_config_list = std::move(*decoded);
 
   if (target_name_value) {
diff --git a/net/base/connection_endpoint_metadata.h b/net/base/connection_endpoint_metadata.h
index eeeac225..75a582a7 100644
--- a/net/base/connection_endpoint_metadata.h
+++ b/net/base/connection_endpoint_metadata.h
@@ -7,13 +7,13 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
 #include <tuple>
 #include <vector>
 
 #include "base/values.h"
 #include "net/base/net_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -43,7 +43,7 @@
   }
 
   base::Value ToValue() const;
-  static absl::optional<ConnectionEndpointMetadata> FromValue(
+  static std::optional<ConnectionEndpointMetadata> FromValue(
       const base::Value& value);
 
   // ALPN strings for protocols supported by the endpoint. Empty for default
diff --git a/net/base/data_url.cc b/net/base/data_url.cc
index 032e128..4adad74 100644
--- a/net/base/data_url.cc
+++ b/net/base/data_url.cc
@@ -6,13 +6,14 @@
 
 #include "net/base/data_url.h"
 
+#include <string_view>
+
 #include "base/base64.h"
 #include "base/containers/cxx20_erase.h"
 #include "base/feature_list.h"
 #include "base/features.h"
 #include "base/ranges/algorithm.h"
 #include "base/strings/escape.h"
-#include "base/strings/string_piece.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "net/base/mime_util.h"
@@ -34,7 +35,7 @@
 //   - Doesn't need any extra padding.
 //   - Does not have any escaped characters.
 //   - Does not have any whitespace.
-bool IsDataURLReadyForDecode(base::StringPiece body) {
+bool IsDataURLReadyForDecode(std::string_view body) {
   return (body.length() % 4) == 0 && base::ranges::none_of(body, [](char c) {
            return c == '%' || IsBase64Whitespace(c);
          });
@@ -53,7 +54,7 @@
   DCHECK(charset->empty());
   DCHECK(!data || data->empty());
 
-  base::StringPiece content;
+  std::string_view content;
   std::string content_string;
   if (base::FeatureList::IsEnabled(base::features::kOptimizeDataUrls)) {
     // Avoid copying the URL content which can be expensive for large URLs.
@@ -63,11 +64,11 @@
     content = content_string;
   }
 
-  base::StringPiece::const_iterator comma = base::ranges::find(content, ',');
+  std::string_view::const_iterator comma = base::ranges::find(content, ',');
   if (comma == content.end())
     return false;
 
-  std::vector<base::StringPiece> meta_data =
+  std::vector<std::string_view> meta_data =
       base::SplitStringPiece(base::MakeStringPiece(content.begin(), comma), ";",
                              base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
 
@@ -80,8 +81,8 @@
     ++iter;
   }
 
-  static constexpr base::StringPiece kBase64Tag("base64");
-  static constexpr base::StringPiece kCharsetTag("charset=");
+  static constexpr std::string_view kBase64Tag("base64");
+  static constexpr std::string_view kCharsetTag("charset=");
 
   bool base64_encoded = false;
   for (; iter != meta_data.cend(); ++iter) {
@@ -166,7 +167,7 @@
 }
 
 Error DataURL::BuildResponse(const GURL& url,
-                             base::StringPiece method,
+                             std::string_view method,
                              std::string* mime_type,
                              std::string* charset,
                              std::string* data,
diff --git a/net/base/data_url.h b/net/base/data_url.h
index 066d5d5..6fee5ef6 100644
--- a/net/base/data_url.h
+++ b/net/base/data_url.h
@@ -6,9 +6,9 @@
 #define NET_BASE_DATA_URL_H_
 
 #include <string>
+#include <string_view>
 
 #include "base/memory/scoped_refptr.h"
-#include "base/strings/string_piece.h"
 #include "net/base/net_errors.h"
 #include "net/base/net_export.h"
 
@@ -74,7 +74,7 @@
   // strings, and |*headers| must be nullptr. Returns net::OK on success.
   [[nodiscard]] static Error BuildResponse(
       const GURL& url,
-      base::StringPiece method,
+      std::string_view method,
       std::string* mime_type,
       std::string* charset,
       std::string* data,
diff --git a/net/base/elements_upload_data_stream_unittest.cc b/net/base/elements_upload_data_stream_unittest.cc
index 762315b..f205f55 100644
--- a/net/base/elements_upload_data_stream_unittest.cc
+++ b/net/base/elements_upload_data_stream_unittest.cc
@@ -8,6 +8,7 @@
 
 #include <algorithm>
 #include <limits>
+#include <string_view>
 #include <vector>
 
 #include "base/files/file_path.h"
@@ -16,7 +17,6 @@
 #include "base/functional/bind.h"
 #include "base/location.h"
 #include "base/run_loop.h"
-#include "base/strings/string_piece.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/time/time.h"
 #include "net/base/completion_once_callback.h"
diff --git a/net/base/features.h b/net/base/features.h
index 192f427..1fe88a0 100644
--- a/net/base/features.h
+++ b/net/base/features.h
@@ -6,10 +6,10 @@
 #define NET_BASE_FEATURES_H_
 
 #include <string>
+#include <string_view>
 
 #include "base/feature_list.h"
 #include "base/metrics/field_trial_params.h"
-#include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "crypto/crypto_buildflags.h"
@@ -176,7 +176,7 @@
 // Creates a <double key + is_cross_site> NetworkIsolationKey which is used
 // to partition the HTTP cache. This key will have the following properties:
 // `top_frame_site_` -> the schemeful site of the top level page.
-// `frame_site_` -> absl::nullopt.
+// `frame_site_` -> std::nullopt.
 // `is_cross_site_` -> a boolean indicating whether the frame site is
 // schemefully cross-site from the top-level site.
 NET_EXPORT BASE_DECLARE_FEATURE(kEnableCrossSiteFlagNetworkIsolationKey);
diff --git a/net/base/fuchsia/network_interface_cache.cc b/net/base/fuchsia/network_interface_cache.cc
index 01207df..37ce92b 100644
--- a/net/base/fuchsia/network_interface_cache.cc
+++ b/net/base/fuchsia/network_interface_cache.cc
@@ -6,6 +6,7 @@
 
 #include <fuchsia/net/interfaces/cpp/fidl.h>
 
+#include <optional>
 #include <utility>
 
 #include "base/containers/flat_map.h"
@@ -15,7 +16,6 @@
 #include "net/base/network_change_notifier.h"
 #include "net/base/network_interfaces.h"
 #include "net/base/network_interfaces_fuchsia.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net::internal {
 namespace {
@@ -52,7 +52,7 @@
 
 NetworkInterfaceCache::~NetworkInterfaceCache() = default;
 
-absl::optional<NetworkInterfaceCache::ChangeBits>
+std::optional<NetworkInterfaceCache::ChangeBits>
 NetworkInterfaceCache::AddInterfaces(
     std::vector<fuchsia::net::interfaces::Properties> interfaces) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -63,14 +63,14 @@
   for (auto& interface : interfaces) {
     auto change_bits = AddInterfaceWhileLocked(std::move(interface));
     if (!change_bits.has_value()) {
-      return absl::nullopt;
+      return std::nullopt;
     }
     combined_changes |= change_bits.value();
   }
   return combined_changes;
 }
 
-absl::optional<NetworkInterfaceCache::ChangeBits>
+std::optional<NetworkInterfaceCache::ChangeBits>
 NetworkInterfaceCache::AddInterface(
     fuchsia::net::interfaces::Properties properties) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -80,25 +80,25 @@
   return AddInterfaceWhileLocked(std::move(properties));
 }
 
-absl::optional<NetworkInterfaceCache::ChangeBits>
+std::optional<NetworkInterfaceCache::ChangeBits>
 NetworkInterfaceCache::AddInterfaceWhileLocked(
     fuchsia::net::interfaces::Properties properties)
     EXCLUSIVE_LOCKS_REQUIRED(lock_) VALID_CONTEXT_REQUIRED(sequence_checker_) {
   if (error_state_) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   auto interface = InterfaceProperties::VerifyAndCreate(std::move(properties));
   if (!interface) {
     LOG(ERROR) << "Incomplete interface properties.";
     SetErrorWhileLocked();
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   if (interfaces_.find(interface->id()) != interfaces_.end()) {
     LOG(ERROR) << "Unexpected duplicate interface ID " << interface->id();
     SetErrorWhileLocked();
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   ChangeBits change_bits = kNoChange;
@@ -112,21 +112,21 @@
   return change_bits;
 }
 
-absl::optional<NetworkInterfaceCache::ChangeBits>
+std::optional<NetworkInterfaceCache::ChangeBits>
 NetworkInterfaceCache::ChangeInterface(
     fuchsia::net::interfaces::Properties properties) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   base::AutoLock auto_lock(lock_);
   if (error_state_) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   auto cache_entry = interfaces_.find(properties.id());
   if (cache_entry == interfaces_.end()) {
     LOG(ERROR) << "Unknown interface ID " << properties.id();
     SetErrorWhileLocked();
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   const bool old_can_reach =
@@ -136,7 +136,7 @@
   if (!cache_entry->second.Update(std::move(properties))) {
     LOG(ERROR) << "Update failed";
     SetErrorWhileLocked();
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   const bool new_can_reach =
@@ -152,21 +152,21 @@
   return change_bits;
 }
 
-absl::optional<NetworkInterfaceCache::ChangeBits>
+std::optional<NetworkInterfaceCache::ChangeBits>
 NetworkInterfaceCache::RemoveInterface(
     InterfaceProperties::InterfaceId interface_id) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   base::AutoLock auto_lock(lock_);
   if (error_state_) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   auto cache_entry = interfaces_.find(interface_id);
   if (cache_entry == interfaces_.end()) {
     LOG(ERROR) << "Unknown interface ID " << interface_id;
     SetErrorWhileLocked();
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   ChangeBits change_bits = kNoChange;
diff --git a/net/base/fuchsia/network_interface_cache.h b/net/base/fuchsia/network_interface_cache.h
index 6853079..bcb51c9 100644
--- a/net/base/fuchsia/network_interface_cache.h
+++ b/net/base/fuchsia/network_interface_cache.h
@@ -9,6 +9,8 @@
 #include <stdint.h>
 #include <zircon/errors.h>
 
+#include <optional>
+
 #include "base/containers/flat_map.h"
 #include "base/sequence_checker.h"
 #include "base/thread_annotations.h"
@@ -16,7 +18,6 @@
 #include "net/base/network_change_notifier.h"
 #include "net/base/network_interfaces.h"
 #include "net/base/network_interfaces_fuchsia.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net::internal {
 
@@ -36,7 +37,7 @@
 // - Change/Remove an interface unknown to the cache.
 //
 // After entering error state, all subsequent write operations return
-// `absl::nullopt`, and subsequent read operations will not return a result
+// `std::nullopt`, and subsequent read operations will not return a result
 // (specifically, `GetOnlineInterfaces` returns `false`, and `GetConnectionType`
 // returns `CONNECTION_UNKNOWN`).
 class NET_EXPORT_PRIVATE NetworkInterfaceCache {
@@ -54,23 +55,23 @@
   NetworkInterfaceCache(const NetworkInterfaceCache&) = delete;
   NetworkInterfaceCache& operator=(const NetworkInterfaceCache&) = delete;
 
-  // Returns `absl::nullopt` if any of the interfaces fail to be added. See
+  // Returns `std::nullopt` if any of the interfaces fail to be added. See
   // `AddInterface`.
-  absl::optional<ChangeBits> AddInterfaces(
+  std::optional<ChangeBits> AddInterfaces(
       std::vector<fuchsia::net::interfaces::Properties> interfaces);
 
-  // Returns `absl::nullopt` if `properties` is invalid or incomplete, or if the
+  // Returns `std::nullopt` if `properties` is invalid or incomplete, or if the
   // interface already exists in the cache.
-  absl::optional<ChangeBits> AddInterface(
+  std::optional<ChangeBits> AddInterface(
       fuchsia::net::interfaces::Properties properties);
 
-  // Returns `absl::nullopt` if `properties` is invalid or does not contain an
+  // Returns `std::nullopt` if `properties` is invalid or does not contain an
   // `id`, or if the interface does not exist in the cache.
-  absl::optional<ChangeBits> ChangeInterface(
+  std::optional<ChangeBits> ChangeInterface(
       fuchsia::net::interfaces::Properties properties);
 
-  // Returns `absl::nullopt` if `interface_id` does not exist in the cache.
-  absl::optional<ChangeBits> RemoveInterface(
+  // Returns `std::nullopt` if `interface_id` does not exist in the cache.
+  std::optional<ChangeBits> RemoveInterface(
       InterfaceProperties::InterfaceId interface_id);
 
   // Set cache to unrecoverable error state and clears the cache.
@@ -92,7 +93,7 @@
   bool UpdateConnectionTypeWhileLocked() EXCLUSIVE_LOCKS_REQUIRED(lock_)
       VALID_CONTEXT_REQUIRED(sequence_checker_);
 
-  absl::optional<ChangeBits> AddInterfaceWhileLocked(
+  std::optional<ChangeBits> AddInterfaceWhileLocked(
       fuchsia::net::interfaces::Properties properties)
       EXCLUSIVE_LOCKS_REQUIRED(lock_) VALID_CONTEXT_REQUIRED(sequence_checker_);
 
diff --git a/net/base/hash_value.cc b/net/base/hash_value.cc
index 3020613e..cbee5270 100644
--- a/net/base/hash_value.cc
+++ b/net/base/hash_value.cc
@@ -21,7 +21,7 @@
 
 namespace {
 
-constexpr base::StringPiece kSha256Slash = "sha256/";
+constexpr std::string_view kSha256Slash = "sha256/";
 
 // LessThan comparator for use with std::binary_search() in determining
 // whether a SHA-256 HashValue appears within a sorted array of
@@ -46,12 +46,12 @@
   fingerprint.sha256 = hash;
 }
 
-bool HashValue::FromString(base::StringPiece value) {
+bool HashValue::FromString(std::string_view value) {
   if (!base::StartsWith(value, kSha256Slash)) {
     return false;
   }
 
-  base::StringPiece base64_str = value.substr(kSha256Slash.size());
+  std::string_view base64_str = value.substr(kSha256Slash.size());
 
   auto decoded = base::Base64Decode(base64_str);
   if (!decoded || decoded->size() != size()) {
diff --git a/net/base/hash_value.h b/net/base/hash_value.h
index 465b997..30df6d0 100644
--- a/net/base/hash_value.h
+++ b/net/base/hash_value.h
@@ -10,10 +10,10 @@
 #include <string.h>
 
 #include <string>
+#include <string_view>
 #include <vector>
 
 #include "base/containers/span.h"
-#include "base/strings/string_piece.h"
 #include "build/build_config.h"
 #include "net/base/net_export.h"
 
@@ -70,7 +70,7 @@
 
   // Deserializes a HashValue from a string. Returns false if the input is not
   // valid.
-  bool FromString(base::StringPiece input);
+  bool FromString(std::string_view input);
 
   // Serializes the HashValue to a string.
   std::string ToString() const;
diff --git a/net/base/hex_utils.cc b/net/base/hex_utils.cc
index 2d02935..5f02678 100644
--- a/net/base/hex_utils.cc
+++ b/net/base/hex_utils.cc
@@ -10,14 +10,14 @@
 
 namespace net {
 
-std::string HexDecode(base::StringPiece hex) {
+std::string HexDecode(std::string_view hex) {
   std::string output;
   const bool success = base::HexStringToString(hex, &output);
   DCHECK(success);
   return output;
 }
 
-std::string HexDump(base::StringPiece input) {
+std::string HexDump(std::string_view input) {
   return quiche::QuicheTextUtils::HexDump(input);
 }
 
diff --git a/net/base/hex_utils.h b/net/base/hex_utils.h
index e3e73fe..e8a23358 100644
--- a/net/base/hex_utils.h
+++ b/net/base/hex_utils.h
@@ -6,8 +6,8 @@
 #define NET_BASE_HEX_UTILS_H_
 
 #include <string>
+#include <string_view>
 
-#include "base/strings/string_piece.h"
 #include "net/base/net_export.h"
 
 namespace net {
@@ -18,7 +18,7 @@
 // invalid input in debug builds, therefore it must only be used on sanitized
 // input (like a constant literal).  If validity of input needs to be checked or
 // partial decoding is desired, use base::HexStringToString() instead.
-NET_EXPORT_PRIVATE std::string HexDecode(base::StringPiece hex);
+NET_EXPORT_PRIVATE std::string HexDecode(std::string_view hex);
 
 // Return a std::string containing hex and ASCII representations of the binary
 // buffer |input|, with offsets at the beginning of each line, in the style of
@@ -27,7 +27,7 @@
 // "0x0000:  0090 69bd 5400 000d 610f 0189 0800 4500  ..i.T...a.....E.\n"
 // "0x0010:  001c fb98 4000 4001 7e18 d8ef 2301 455d  ....@.@.~...#.E]\n"
 // "0x0020:  7fe2 0800 6bcb 0bc6 806e                 ....k....n\n"
-NET_EXPORT_PRIVATE std::string HexDump(base::StringPiece input);
+NET_EXPORT_PRIVATE std::string HexDump(std::string_view input);
 
 }  // namespace net
 
diff --git a/net/base/host_mapping_rules.cc b/net/base/host_mapping_rules.cc
index e9de7436..fec058d 100644
--- a/net/base/host_mapping_rules.cc
+++ b/net/base/host_mapping_rules.cc
@@ -104,8 +104,8 @@
   return RewriteResult::kRewritten;
 }
 
-bool HostMappingRules::AddRuleFromString(base::StringPiece rule_string) {
-  std::vector<base::StringPiece> parts = base::SplitStringPiece(
+bool HostMappingRules::AddRuleFromString(std::string_view rule_string) {
+  std::vector<std::string_view> parts = base::SplitStringPiece(
       base::TrimWhitespaceASCII(rule_string, base::TRIM_ALL), " ",
       base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
 
@@ -135,13 +135,13 @@
   return false;
 }
 
-void HostMappingRules::SetRulesFromString(base::StringPiece rules_string) {
+void HostMappingRules::SetRulesFromString(std::string_view rules_string) {
   exclusion_rules_.clear();
   map_rules_.clear();
 
-  std::vector<base::StringPiece> rules = base::SplitStringPiece(
+  std::vector<std::string_view> rules = base::SplitStringPiece(
       rules_string, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
-  for (base::StringPiece rule : rules) {
+  for (std::string_view rule : rules) {
     bool ok = AddRuleFromString(rule);
     LOG_IF(ERROR, !ok) << "Failed parsing rule: " << rule;
   }
diff --git a/net/base/host_mapping_rules.h b/net/base/host_mapping_rules.h
index 57f8b61..8e116c7 100644
--- a/net/base/host_mapping_rules.h
+++ b/net/base/host_mapping_rules.h
@@ -5,9 +5,9 @@
 #ifndef NET_BASE_HOST_MAPPING_RULES_H_
 #define NET_BASE_HOST_MAPPING_RULES_H_
 
+#include <string_view>
 #include <vector>
 
-#include "base/strings/string_piece.h"
 #include "net/base/net_export.h"
 
 class GURL;
@@ -52,10 +52,10 @@
   // The <replacement_host> can be either a hostname, or an IP address literal.
   //
   // Returns true if the rule was successfully parsed and added.
-  bool AddRuleFromString(base::StringPiece rule_string);
+  bool AddRuleFromString(std::string_view rule_string);
 
   // Sets the rules from a comma separated list of rules.
-  void SetRulesFromString(base::StringPiece rules_string);
+  void SetRulesFromString(std::string_view rules_string);
 
  private:
   struct MapRule;
diff --git a/net/base/host_port_pair.cc b/net/base/host_port_pair.cc
index 7bc4f26..14a3e50 100644
--- a/net/base/host_port_pair.cc
+++ b/net/base/host_port_pair.cc
@@ -4,10 +4,12 @@
 
 #include "net/base/host_port_pair.h"
 
+#include <optional>
+#include <string_view>
+
 #include "base/logging.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
@@ -15,7 +17,6 @@
 #include "base/values.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/url_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/scheme_host_port.h"
 
@@ -24,13 +25,13 @@
 namespace {
 
 // Value dictionary keys
-constexpr base::StringPiece kValueHostKey = "host";
-constexpr base::StringPiece kValuePortKey = "port";
+constexpr std::string_view kValueHostKey = "host";
+constexpr std::string_view kValuePortKey = "port";
 
 }  // namespace
 
 HostPortPair::HostPortPair() : port_(0) {}
-HostPortPair::HostPortPair(base::StringPiece in_host, uint16_t in_port)
+HostPortPair::HostPortPair(std::string_view in_host, uint16_t in_port)
     : host_(in_host), port_(in_port) {}
 
 // static
@@ -46,7 +47,7 @@
 
   // HostPortPair assumes hostnames do not have surrounding brackets (as is
   // commonly used for IPv6 literals), so strip them if present.
-  base::StringPiece host = scheme_host_port.host();
+  std::string_view host = scheme_host_port.host();
   if (host.size() >= 2 && host.front() == '[' && host.back() == ']') {
     host = host.substr(1, host.size() - 2);
   }
@@ -60,7 +61,7 @@
 }
 
 // static
-HostPortPair HostPortPair::FromString(base::StringPiece str) {
+HostPortPair HostPortPair::FromString(std::string_view str) {
   // Input with more than one ':' is ambiguous unless it contains an IPv6
   // literal (signified by starting with a '['). ParseHostAndPort() allows such
   // input and always uses the last ':' as the host/port delimiter, but because
@@ -87,17 +88,17 @@
 }
 
 // static
-absl::optional<HostPortPair> HostPortPair::FromValue(const base::Value& value) {
+std::optional<HostPortPair> HostPortPair::FromValue(const base::Value& value) {
   const base::Value::Dict* dict = value.GetIfDict();
   if (!dict)
-    return absl::nullopt;
+    return std::nullopt;
 
   const std::string* host = dict->FindString(kValueHostKey);
-  absl::optional<int> port = dict->FindInt(kValuePortKey);
+  std::optional<int> port = dict->FindInt(kValuePortKey);
 
   if (host == nullptr || !port.has_value() ||
       !base::IsValueInRangeForNumericType<uint16_t>(port.value())) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return HostPortPair(*host, base::checked_cast<uint16_t>(port.value()));
diff --git a/net/base/host_port_pair.h b/net/base/host_port_pair.h
index d694af2..5fce0c6 100644
--- a/net/base/host_port_pair.h
+++ b/net/base/host_port_pair.h
@@ -7,13 +7,13 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <string>
+#include <string_view>
 #include <tuple>
 
-#include "base/strings/string_piece.h"
 #include "base/values.h"
 #include "net/base/net_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class GURL;
 
@@ -29,7 +29,7 @@
  public:
   HostPortPair();
   // If |in_host| represents an IPv6 address, it should not bracket the address.
-  HostPortPair(base::StringPiece in_host, uint16_t in_port);
+  HostPortPair(std::string_view in_host, uint16_t in_port);
 
   // Creates a HostPortPair for the origin of |url|.
   static HostPortPair FromURL(const GURL& url);
@@ -42,10 +42,10 @@
 
   // Creates a HostPortPair from a string formatted in same manner as
   // ToString().
-  static HostPortPair FromString(base::StringPiece str);
+  static HostPortPair FromString(std::string_view str);
 
   // Nullopt if `value` is malformed to be deserialized to HostPortPair.
-  static absl::optional<HostPortPair> FromValue(const base::Value& value);
+  static std::optional<HostPortPair> FromValue(const base::Value& value);
 
   // TODO(willchan): Define a functor instead.
   // Comparator function so this can be placed in a std::map.
diff --git a/net/base/host_port_pair_unittest.cc b/net/base/host_port_pair_unittest.cc
index 0ee593b9..7327bad 100644
--- a/net/base/host_port_pair_unittest.cc
+++ b/net/base/host_port_pair_unittest.cc
@@ -4,11 +4,12 @@
 
 #include "net/base/host_port_pair.h"
 
+#include <optional>
+
 #include "base/values.h"
 #include "net/test/gtest_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/scheme_host_port.h"
 
diff --git a/net/base/ip_address.cc b/net/base/ip_address.cc
index 49934db..ed51e79 100644
--- a/net/base/ip_address.cc
+++ b/net/base/ip_address.cc
@@ -9,6 +9,8 @@
 #include <algorithm>
 #include <array>
 #include <climits>
+#include <optional>
+#include <string_view>
 
 #include "base/check_op.h"
 #include "base/debug/alias.h"
@@ -17,13 +19,11 @@
 #include "base/notreached.h"
 #include "base/ranges/algorithm.h"
 #include "base/strings/strcat.h"
-#include "base/strings/string_piece.h"
 #include "base/strings/string_split.h"
 #include "base/strings/stringprintf.h"
 #include "base/trace_event/memory_usage_estimator.h"
 #include "base/values.h"
 #include "net/base/parse_number.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/url_canon_ip.h"
 
@@ -121,11 +121,10 @@
   return false;
 }
 
-bool ParseIPLiteralToBytes(base::StringPiece ip_literal,
-                           IPAddressBytes* bytes) {
+bool ParseIPLiteralToBytes(std::string_view ip_literal, IPAddressBytes* bytes) {
   // |ip_literal| could be either an IPv4 or an IPv6 literal. If it contains
   // a colon however, it must be an IPv6 address.
-  if (ip_literal.find(':') != base::StringPiece::npos) {
+  if (ip_literal.find(':') != std::string_view::npos) {
     // GURL expects IPv6 hostnames to be surrounded with brackets.
     std::string host_brackets = base::StrCat({"[", ip_literal, "]"});
     url::Component host_comp(0, host_brackets.size());
@@ -193,20 +192,19 @@
 }
 
 // static
-absl::optional<IPAddress> IPAddress::FromValue(const base::Value& value) {
+std::optional<IPAddress> IPAddress::FromValue(const base::Value& value) {
   if (!value.is_string()) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return IPAddress::FromIPLiteral(value.GetString());
 }
 
 // static
-absl::optional<IPAddress> IPAddress::FromIPLiteral(
-    base::StringPiece ip_literal) {
+std::optional<IPAddress> IPAddress::FromIPLiteral(std::string_view ip_literal) {
   IPAddress address;
   if (!address.AssignFromIPLiteral(ip_literal)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   DCHECK(address.IsValid());
   return address;
@@ -321,7 +319,7 @@
   return IsIPv6() && ((ip_address_[0] & 0xFE) == 0xFC);
 }
 
-bool IPAddress::AssignFromIPLiteral(base::StringPiece ip_literal) {
+bool IPAddress::AssignFromIPLiteral(std::string_view ip_literal) {
   bool success = ParseIPLiteralToBytes(ip_literal, &ip_address_);
   if (!success)
     ip_address_.Resize(0);
@@ -466,14 +464,14 @@
                               prefix_length_in_bits);
 }
 
-bool ParseCIDRBlock(base::StringPiece cidr_literal,
+bool ParseCIDRBlock(std::string_view cidr_literal,
                     IPAddress* ip_address,
                     size_t* prefix_length_in_bits) {
   // We expect CIDR notation to match one of these two templates:
   //   <IPv4-literal> "/" <number of bits>
   //   <IPv6-literal> "/" <number of bits>
 
-  std::vector<base::StringPiece> parts = base::SplitStringPiece(
+  std::vector<std::string_view> parts = base::SplitStringPiece(
       cidr_literal, "/", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
   if (parts.size() != 2)
     return false;
@@ -496,13 +494,12 @@
   return true;
 }
 
-bool ParseURLHostnameToAddress(base::StringPiece hostname,
+bool ParseURLHostnameToAddress(std::string_view hostname,
                                IPAddress* ip_address) {
   if (hostname.size() >= 2 && hostname.front() == '[' &&
       hostname.back() == ']') {
     // Strip the square brackets that surround IPv6 literals.
-    auto ip_literal =
-        base::StringPiece(hostname).substr(1, hostname.size() - 2);
+    auto ip_literal = std::string_view(hostname).substr(1, hostname.size() - 2);
     return ip_address->AssignFromIPLiteral(ip_literal) && ip_address->IsIPv6();
   }
 
diff --git a/net/base/ip_address.h b/net/base/ip_address.h
index c347480..3e965e4 100644
--- a/net/base/ip_address.h
+++ b/net/base/ip_address.h
@@ -10,15 +10,15 @@
 
 #include <algorithm>
 #include <array>
+#include <optional>
 #include <string>
+#include <string_view>
 #include <vector>
 
 #include "base/check_op.h"
 #include "base/containers/span.h"
-#include "base/strings/string_piece.h"
 #include "base/values.h"
 #include "net/base/net_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -109,11 +109,11 @@
   enum : size_t { kIPv4AddressSize = 4, kIPv6AddressSize = 16 };
 
   // Nullopt if `value` is malformed to be deserialized to IPAddress.
-  static absl::optional<IPAddress> FromValue(const base::Value& value);
+  static std::optional<IPAddress> FromValue(const base::Value& value);
 
   // Parses an IP address literal (either IPv4 or IPv6). Returns the resulting
   // IPAddress on success, or nullopt on error.
-  static absl::optional<IPAddress> FromIPLiteral(base::StringPiece ip_literal);
+  static std::optional<IPAddress> FromIPLiteral(std::string_view ip_literal);
 
   // Creates a zero-sized, invalid address.
   IPAddress();
@@ -204,7 +204,7 @@
   //
   // When parsing fails, the original value of |this| will be overwritten such
   // that |this->empty()| and |!this->IsValid()|.
-  [[nodiscard]] bool AssignFromIPLiteral(base::StringPiece ip_literal);
+  [[nodiscard]] bool AssignFromIPLiteral(std::string_view ip_literal);
 
   // Returns the underlying bytes.
   const IPAddressBytes& bytes() const { return ip_address_; }
@@ -288,7 +288,7 @@
 //    10.10.3.1/20
 //    a:b:c::/46
 //    ::1/128
-NET_EXPORT bool ParseCIDRBlock(base::StringPiece cidr_literal,
+NET_EXPORT bool ParseCIDRBlock(std::string_view cidr_literal,
                                IPAddress* ip_address,
                                size_t* prefix_length_in_bits);
 
@@ -298,7 +298,7 @@
 // surrounded by brackets as in [::1]. On failure |ip_address| may have been
 // overwritten and could contain an invalid IPAddress.
 [[nodiscard]] NET_EXPORT bool ParseURLHostnameToAddress(
-    base::StringPiece hostname,
+    std::string_view hostname,
     IPAddress* ip_address);
 
 // Returns number of matching initial bits between the addresses |a1| and |a2|.
diff --git a/net/base/ip_address_unittest.cc b/net/base/ip_address_unittest.cc
index 047c0b0c..526f7c5 100644
--- a/net/base/ip_address_unittest.cc
+++ b/net/base/ip_address_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "net/base/ip_address.h"
 
+#include <optional>
 #include <vector>
 
 #include "base/format_macros.h"
@@ -11,7 +12,6 @@
 #include "base/strings/stringprintf.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 using testing::Optional;
 
diff --git a/net/base/ip_endpoint.cc b/net/base/ip_endpoint.cc
index 7947b58..d9e41d1 100644
--- a/net/base/ip_endpoint.cc
+++ b/net/base/ip_endpoint.cc
@@ -4,9 +4,10 @@
 
 #include "net/base/ip_endpoint.h"
 
-#include <ostream>
-
 #include <string.h>
+
+#include <optional>
+#include <ostream>
 #include <tuple>
 #include <utility>
 
@@ -20,7 +21,6 @@
 #include "build/build_config.h"
 #include "net/base/ip_address.h"
 #include "net/base/sys_addrinfo.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_WIN)
 #include <winsock2.h>
@@ -34,30 +34,30 @@
 namespace {
 
 // Value dictionary keys
-constexpr base::StringPiece kValueAddressKey = "address";
-constexpr base::StringPiece kValuePortKey = "port";
+constexpr std::string_view kValueAddressKey = "address";
+constexpr std::string_view kValuePortKey = "port";
 
 }  // namespace
 
 // static
-absl::optional<IPEndPoint> IPEndPoint::FromValue(const base::Value& value) {
+std::optional<IPEndPoint> IPEndPoint::FromValue(const base::Value& value) {
   const base::Value::Dict* dict = value.GetIfDict();
   if (!dict)
-    return absl::nullopt;
+    return std::nullopt;
 
   const base::Value* address_value = dict->Find(kValueAddressKey);
   if (!address_value)
-    return absl::nullopt;
-  absl::optional<IPAddress> address = IPAddress::FromValue(*address_value);
+    return std::nullopt;
+  std::optional<IPAddress> address = IPAddress::FromValue(*address_value);
   if (!address.has_value())
-    return absl::nullopt;
+    return std::nullopt;
   // Expect IPAddress to only allow deserializing valid addresses.
   DCHECK(address.value().IsValid());
 
-  absl::optional<int> port = dict->FindInt(kValuePortKey);
+  std::optional<int> port = dict->FindInt(kValuePortKey);
   if (!port.has_value() ||
       !base::IsValueInRangeForNumericType<uint16_t>(port.value())) {
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   return IPEndPoint(address.value(),
diff --git a/net/base/ip_endpoint.h b/net/base/ip_endpoint.h
index fa77f35..de6bef1f 100644
--- a/net/base/ip_endpoint.h
+++ b/net/base/ip_endpoint.h
@@ -7,6 +7,7 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <ostream>
 #include <string>
 
@@ -15,7 +16,6 @@
 #include "net/base/address_family.h"
 #include "net/base/ip_address.h"
 #include "net/base/net_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 // Replicate these from Windows headers to avoid pulling net/sys_addrinfo.h.
 // Doing that transitively brings in windows.h. Including windows.h pollutes the
@@ -39,7 +39,7 @@
 class NET_EXPORT IPEndPoint {
  public:
   // Nullopt if `value` is malformed to be serialized to IPEndPoint.
-  static absl::optional<IPEndPoint> FromValue(const base::Value& value);
+  static std::optional<IPEndPoint> FromValue(const base::Value& value);
 
   IPEndPoint();
   ~IPEndPoint();
diff --git a/net/base/ip_endpoint_unittest.cc b/net/base/ip_endpoint_unittest.cc
index 355f882c..204de09 100644
--- a/net/base/ip_endpoint_unittest.cc
+++ b/net/base/ip_endpoint_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <string.h>
 
+#include <optional>
 #include <string>
 #include <tuple>
 
@@ -22,7 +23,6 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 #if BUILDFLAG(IS_WIN)
 #include <winsock2.h>
diff --git a/net/base/isolation_info.cc b/net/base/isolation_info.cc
index e337af6..c58b63d 100644
--- a/net/base/isolation_info.cc
+++ b/net/base/isolation_info.cc
@@ -5,6 +5,7 @@
 #include "net/base/isolation_info.h"
 
 #include <cstddef>
+#include <optional>
 
 #include "base/check_op.h"
 #include "base/unguessable_token.h"
@@ -13,7 +14,6 @@
 #include "net/base/isolation_info.pb.h"
 #include "net/base/network_anonymization_key.h"
 #include "net/base/proxy_server.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -45,10 +45,10 @@
 // descriptions of consistent sets of values. Also allows values used by the
 // 0-argument constructor.
 bool IsConsistent(IsolationInfo::RequestType request_type,
-                  const absl::optional<url::Origin>& top_frame_origin,
-                  const absl::optional<url::Origin>& frame_origin,
+                  const std::optional<url::Origin>& top_frame_origin,
+                  const std::optional<url::Origin>& frame_origin,
                   const SiteForCookies& site_for_cookies,
-                  const absl::optional<base::UnguessableToken>& nonce) {
+                  const std::optional<base::UnguessableToken>& nonce) {
   // Check for the default-constructed case.
   if (!top_frame_origin) {
     return request_type == IsolationInfo::RequestType::kOther &&
@@ -92,10 +92,10 @@
 
 IsolationInfo::IsolationInfo()
     : IsolationInfo(RequestType::kOther,
-                    /*top_frame_origin=*/absl::nullopt,
-                    /*frame_origin=*/absl::nullopt,
+                    /*top_frame_origin=*/std::nullopt,
+                    /*frame_origin=*/std::nullopt,
                     SiteForCookies(),
-                    /*nonce=*/absl::nullopt) {}
+                    /*nonce=*/std::nullopt) {}
 
 IsolationInfo::IsolationInfo(const IsolationInfo&) = default;
 IsolationInfo::IsolationInfo(IsolationInfo&&) = default;
@@ -107,26 +107,26 @@
     const url::Origin& top_frame_origin) {
   return IsolationInfo(RequestType::kOther, top_frame_origin, top_frame_origin,
                        SiteForCookies::FromOrigin(top_frame_origin),
-                       /*nonce=*/absl::nullopt);
+                       /*nonce=*/std::nullopt);
 }
 
 IsolationInfo IsolationInfo::CreateTransient() {
   url::Origin opaque_origin;
   return IsolationInfo(RequestType::kOther, opaque_origin, opaque_origin,
-                       SiteForCookies(), /*nonce=*/absl::nullopt);
+                       SiteForCookies(), /*nonce=*/std::nullopt);
 }
 
-absl::optional<IsolationInfo> IsolationInfo::Deserialize(
+std::optional<IsolationInfo> IsolationInfo::Deserialize(
     const std::string& serialized) {
   proto::IsolationInfo proto;
   if (!proto.ParseFromString(serialized))
-    return absl::nullopt;
+    return std::nullopt;
 
-  absl::optional<url::Origin> top_frame_origin;
+  std::optional<url::Origin> top_frame_origin;
   if (proto.has_top_frame_origin())
     top_frame_origin = url::Origin::Create(GURL(proto.top_frame_origin()));
 
-  absl::optional<url::Origin> frame_origin;
+  std::optional<url::Origin> frame_origin;
   if (proto.has_frame_origin())
     frame_origin = url::Origin::Create(GURL(proto.frame_origin()));
 
@@ -134,7 +134,7 @@
       static_cast<RequestType>(proto.request_type()),
       std::move(top_frame_origin), std::move(frame_origin),
       SiteForCookies::FromUrl(GURL(proto.site_for_cookies())),
-      /*nonce=*/absl::nullopt);
+      /*nonce=*/std::nullopt);
 }
 
 IsolationInfo IsolationInfo::Create(
@@ -142,7 +142,7 @@
     const url::Origin& top_frame_origin,
     const url::Origin& frame_origin,
     const SiteForCookies& site_for_cookies,
-    const absl::optional<base::UnguessableToken>& nonce) {
+    const std::optional<base::UnguessableToken>& nonce) {
   return IsolationInfo(request_type, top_frame_origin, frame_origin,
                        site_for_cookies, nonce);
 }
@@ -156,7 +156,7 @@
   url::Origin top_frame_origin =
       network_anonymization_key.GetTopFrameSite()->site_as_origin_;
 
-  absl::optional<url::Origin> frame_origin;
+  std::optional<url::Origin> frame_origin;
   if (network_anonymization_key.IsCrossSite()) {
     // If we know that the origin is cross site to the top level site, create an
     // empty origin to use as the frame origin for the isolation info. This
@@ -168,7 +168,7 @@
     frame_origin = top_frame_origin;
   }
 
-  const absl::optional<base::UnguessableToken>& nonce =
+  const std::optional<base::UnguessableToken>& nonce =
       network_anonymization_key.GetNonce();
 
   auto isolation_info = IsolationInfo::Create(
@@ -178,15 +178,15 @@
   return isolation_info;
 }
 
-absl::optional<IsolationInfo> IsolationInfo::CreateIfConsistent(
+std::optional<IsolationInfo> IsolationInfo::CreateIfConsistent(
     RequestType request_type,
-    const absl::optional<url::Origin>& top_frame_origin,
-    const absl::optional<url::Origin>& frame_origin,
+    const std::optional<url::Origin>& top_frame_origin,
+    const std::optional<url::Origin>& frame_origin,
     const SiteForCookies& site_for_cookies,
-    const absl::optional<base::UnguessableToken>& nonce) {
+    const std::optional<base::UnguessableToken>& nonce) {
   if (!IsConsistent(request_type, top_frame_origin, frame_origin,
                     site_for_cookies, nonce)) {
-    return absl::nullopt;
+    return std::nullopt;
   }
   return IsolationInfo(request_type, top_frame_origin, frame_origin,
                        site_for_cookies, nonce);
@@ -207,11 +207,11 @@
                        SiteForCookies::FromOrigin(new_origin), nonce_);
 }
 
-const absl::optional<url::Origin>& IsolationInfo::frame_origin() const {
+const std::optional<url::Origin>& IsolationInfo::frame_origin() const {
   return frame_origin_;
 }
 
-const absl::optional<url::Origin>& IsolationInfo::frame_origin_for_testing()
+const std::optional<url::Origin>& IsolationInfo::frame_origin_for_testing()
     const {
   return frame_origin_;
 }
@@ -295,9 +295,9 @@
 
 NetworkAnonymizationKey
 IsolationInfo::CreateNetworkAnonymizationKeyForIsolationInfo(
-    const absl::optional<url::Origin>& top_frame_origin,
-    const absl::optional<url::Origin>& frame_origin,
-    const absl::optional<base::UnguessableToken>& nonce) const {
+    const std::optional<url::Origin>& top_frame_origin,
+    const std::optional<url::Origin>& frame_origin,
+    const std::optional<base::UnguessableToken>& nonce) const {
   if (!top_frame_origin) {
     return NetworkAnonymizationKey();
   }
@@ -308,12 +308,11 @@
                                                       frame_site, nonce);
 }
 
-IsolationInfo::IsolationInfo(
-    RequestType request_type,
-    const absl::optional<url::Origin>& top_frame_origin,
-    const absl::optional<url::Origin>& frame_origin,
-    const SiteForCookies& site_for_cookies,
-    const absl::optional<base::UnguessableToken>& nonce)
+IsolationInfo::IsolationInfo(RequestType request_type,
+                             const std::optional<url::Origin>& top_frame_origin,
+                             const std::optional<url::Origin>& frame_origin,
+                             const SiteForCookies& site_for_cookies,
+                             const std::optional<base::UnguessableToken>& nonce)
     : request_type_(request_type),
       top_frame_origin_(top_frame_origin),
       frame_origin_(frame_origin),
diff --git a/net/base/isolation_info.h b/net/base/isolation_info.h
index 8de58d6..c391feb 100644
--- a/net/base/isolation_info.h
+++ b/net/base/isolation_info.h
@@ -5,6 +5,7 @@
 #ifndef NET_BASE_ISOLATION_INFO_H_
 #define NET_BASE_ISOLATION_INFO_H_
 
+#include <optional>
 #include <set>
 #include <string>
 
@@ -13,7 +14,6 @@
 #include "net/base/network_anonymization_key.h"
 #include "net/base/network_isolation_key.h"
 #include "net/cookies/site_for_cookies.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/origin.h"
 
 namespace network::mojom {
@@ -91,7 +91,7 @@
 
   // Creates an IsolationInfo from the serialized contents. Returns a nullopt
   // if deserialization fails or if data is inconsistent.
-  static absl::optional<IsolationInfo> Deserialize(
+  static std::optional<IsolationInfo> Deserialize(
       const std::string& serialized);
 
   // Creates an IsolationInfo with the provided parameters. If the parameters
@@ -114,7 +114,7 @@
       const url::Origin& top_frame_origin,
       const url::Origin& frame_origin,
       const SiteForCookies& site_for_cookies,
-      const absl::optional<base::UnguessableToken>& nonce = absl::nullopt);
+      const std::optional<base::UnguessableToken>& nonce = std::nullopt);
 
   // TODO(crbug/1372769): Remove this and create a safer way to ensure NIKs
   // created from NAKs aren't used by accident.
@@ -127,12 +127,12 @@
   // considered consistent.
   //
   // Intended for use by cross-process deserialization.
-  static absl::optional<IsolationInfo> CreateIfConsistent(
+  static std::optional<IsolationInfo> CreateIfConsistent(
       RequestType request_type,
-      const absl::optional<url::Origin>& top_frame_origin,
-      const absl::optional<url::Origin>& frame_origin,
+      const std::optional<url::Origin>& top_frame_origin,
+      const std::optional<url::Origin>& frame_origin,
       const SiteForCookies& site_for_cookies,
-      const absl::optional<base::UnguessableToken>& nonce = absl::nullopt);
+      const std::optional<base::UnguessableToken>& nonce = std::nullopt);
 
   // Create a new IsolationInfo for a redirect to the supplied origin. |this| is
   // unmodified.
@@ -148,10 +148,10 @@
   // Note that these are the values the IsolationInfo was created with. In the
   // case an IsolationInfo was created from a NetworkIsolationKey, they may be
   // scheme + eTLD+1 instead of actual origins.
-  const absl::optional<url::Origin>& top_frame_origin() const {
+  const std::optional<url::Origin>& top_frame_origin() const {
     return top_frame_origin_;
   }
-  const absl::optional<url::Origin>& frame_origin() const;
+  const std::optional<url::Origin>& frame_origin() const;
 
   const NetworkIsolationKey& network_isolation_key() const {
     return network_isolation_key_;
@@ -161,7 +161,7 @@
     return network_anonymization_key_;
   }
 
-  const absl::optional<base::UnguessableToken>& nonce() const { return nonce_; }
+  const std::optional<base::UnguessableToken>& nonce() const { return nonce_; }
 
   // The value that should be consulted for the third-party cookie blocking
   // policy, as defined in Section 2.1.1 and 2.1.2 of
@@ -172,14 +172,14 @@
   const SiteForCookies& site_for_cookies() const { return site_for_cookies_; }
 
   // Do not use outside of testing. Returns the `frame_origin_`.
-  const absl::optional<url::Origin>& frame_origin_for_testing() const;
+  const std::optional<url::Origin>& frame_origin_for_testing() const;
 
   bool IsEqualForTesting(const IsolationInfo& other) const;
 
   NetworkAnonymizationKey CreateNetworkAnonymizationKeyForIsolationInfo(
-      const absl::optional<url::Origin>& top_frame_origin,
-      const absl::optional<url::Origin>& frame_origin,
-      const absl::optional<base::UnguessableToken>& nonce) const;
+      const std::optional<url::Origin>& top_frame_origin,
+      const std::optional<url::Origin>& frame_origin,
+      const std::optional<base::UnguessableToken>& nonce) const;
 
   // Serialize the `IsolationInfo` into a string. Fails if transient, returning
   // an empty string.
@@ -189,15 +189,15 @@
 
  private:
   IsolationInfo(RequestType request_type,
-                const absl::optional<url::Origin>& top_frame_origin,
-                const absl::optional<url::Origin>& frame_origin,
+                const std::optional<url::Origin>& top_frame_origin,
+                const std::optional<url::Origin>& frame_origin,
                 const SiteForCookies& site_for_cookies,
-                const absl::optional<base::UnguessableToken>& nonce);
+                const std::optional<base::UnguessableToken>& nonce);
 
   RequestType request_type_;
 
-  absl::optional<url::Origin> top_frame_origin_;
-  absl::optional<url::Origin> frame_origin_;
+  std::optional<url::Origin> top_frame_origin_;
+  std::optional<url::Origin> frame_origin_;
 
   // This can be deduced from the two origins above, but keep a cached version
   // to avoid repeated eTLD+1 calculations, when this is using eTLD+1.
@@ -209,7 +209,7 @@
 
   // Having a nonce is a way to force a transient opaque `IsolationInfo`
   // for non-opaque origins.
-  absl::optional<base::UnguessableToken> nonce_;
+  std::optional<base::UnguessableToken> nonce_;
 
   // Mojo serialization code needs to access internal fields.
   friend struct mojo::StructTraits<network::mojom::IsolationInfoDataView,
diff --git a/net/base/isolation_info_unittest.cc b/net/base/isolation_info_unittest.cc
index 7b6117c..7f897694 100644
--- a/net/base/isolation_info_unittest.cc
+++ b/net/base/isolation_info_unittest.cc
@@ -5,6 +5,8 @@
 #include "net/base/isolation_info.h"
 
 #include <iostream>
+#include <optional>
+
 #include "base/strings/strcat.h"
 #include "base/test/gtest_util.h"
 #include "base/test/scoped_feature_list.h"
@@ -16,7 +18,6 @@
 #include "net/base/schemeful_site.h"
 #include "net/cookies/site_for_cookies.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 #include "url/url_util.h"
@@ -87,7 +88,7 @@
     });
 
 void DuplicateAndCompare(const IsolationInfo& isolation_info) {
-  absl::optional<IsolationInfo> duplicate_isolation_info =
+  std::optional<IsolationInfo> duplicate_isolation_info =
       IsolationInfo::CreateIfConsistent(
           isolation_info.request_type(), isolation_info.top_frame_origin(),
           isolation_info.frame_origin(), isolation_info.site_for_cookies(),
@@ -291,7 +292,7 @@
   EXPECT_EQ(kOrigin1, isolation_info.frame_origin());
   EXPECT_TRUE(isolation_info.network_isolation_key().IsFullyPopulated());
   EXPECT_TRUE(isolation_info.network_isolation_key().IsTransient());
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             isolation_info.network_isolation_key().ToCacheKeyString());
   EXPECT_TRUE(
       isolation_info.site_for_cookies().IsFirstParty(kOrigin1.GetURL()));
@@ -309,7 +310,7 @@
       redirected_isolation_info.network_isolation_key().IsFullyPopulated());
   EXPECT_TRUE(redirected_isolation_info.network_isolation_key().IsTransient());
   EXPECT_EQ(
-      absl::nullopt,
+      std::nullopt,
       redirected_isolation_info.network_isolation_key().ToCacheKeyString());
   EXPECT_TRUE(redirected_isolation_info.site_for_cookies().IsFirstParty(
       kOrigin3.GetURL()));
@@ -326,7 +327,7 @@
   EXPECT_EQ(kOrigin2, isolation_info.frame_origin());
   EXPECT_TRUE(isolation_info.network_isolation_key().IsFullyPopulated());
   EXPECT_TRUE(isolation_info.network_isolation_key().IsTransient());
-  EXPECT_EQ(absl::nullopt,
+  EXPECT_EQ(std::nullopt,
             isolation_info.network_isolation_key().ToCacheKeyString());
   EXPECT_TRUE(
       isolation_info.site_for_cookies().IsFirstParty(kOrigin1.GetURL()));
@@ -344,7 +345,7 @@
       redirected_isolation_info.network_isolation_key().IsFullyPopulated());
   EXPECT_TRUE(redirected_isolation_info.network_isolation_key().IsTransient());
   EXPECT_EQ(
-      absl::nullopt,
+      std::nullopt,
       redirected_isolation_info.network_isolation_key().ToCacheKeyString());
   EXPECT_TRUE(redirected_isolation_info.site_for_cookies().IsFirstParty(
       kOrigin1.GetURL()));
@@ -542,26 +543,26 @@
 
   // Correctly have empty/non-empty origins:
   EXPECT_TRUE(IsolationInfo::CreateIfConsistent(
-      IsolationInfo::RequestType::kOther, absl::nullopt, absl::nullopt,
+      IsolationInfo::RequestType::kOther, std::nullopt, std::nullopt,
       SiteForCookies()));
 
   // Incorrectly have empty/non-empty origins:
   EXPECT_FALSE(IsolationInfo::CreateIfConsistent(
-      IsolationInfo::RequestType::kOther, absl::nullopt, kOrigin1,
+      IsolationInfo::RequestType::kOther, std::nullopt, kOrigin1,
       SiteForCookies()));
   EXPECT_FALSE(IsolationInfo::CreateIfConsistent(
-      IsolationInfo::RequestType::kSubFrame, absl::nullopt, kOrigin2,
+      IsolationInfo::RequestType::kSubFrame, std::nullopt, kOrigin2,
       SiteForCookies()));
 
   // Empty frame origins are incorrect.
   EXPECT_FALSE(IsolationInfo::CreateIfConsistent(
-      IsolationInfo::RequestType::kOther, kOrigin1, absl::nullopt,
+      IsolationInfo::RequestType::kOther, kOrigin1, std::nullopt,
       SiteForCookies()));
   EXPECT_FALSE(IsolationInfo::CreateIfConsistent(
-      IsolationInfo::RequestType::kSubFrame, kOrigin1, absl::nullopt,
+      IsolationInfo::RequestType::kSubFrame, kOrigin1, std::nullopt,
       SiteForCookies()));
   EXPECT_FALSE(IsolationInfo::CreateIfConsistent(
-      IsolationInfo::RequestType::kMainFrame, kOrigin1, absl::nullopt,
+      IsolationInfo::RequestType::kMainFrame, kOrigin1, std::nullopt,
       SiteForCookies::FromOrigin(kOrigin1)));
   EXPECT_FALSE(IsolationInfo::CreateIfConsistent(
       IsolationInfo::RequestType::kOther, kOrigin1, kOrigin2,
@@ -569,12 +570,12 @@
 
   // No origins with non-null SiteForCookies.
   EXPECT_FALSE(IsolationInfo::CreateIfConsistent(
-      IsolationInfo::RequestType::kOther, absl::nullopt, absl::nullopt,
+      IsolationInfo::RequestType::kOther, std::nullopt, std::nullopt,
       SiteForCookies::FromOrigin(kOrigin1)));
 
   // No origins with non-null nonce.
   EXPECT_FALSE(IsolationInfo::CreateIfConsistent(
-      IsolationInfo::RequestType::kOther, absl::nullopt, absl::nullopt,
+      IsolationInfo::RequestType::kOther, std::nullopt, std::nullopt,
       SiteForCookies(), kNonce1));
 }
 
diff --git a/net/base/lookup_string_in_fixed_set.cc b/net/base/lookup_string_in_fixed_set.cc
index 9956f1f..adbd4e63 100644
--- a/net/base/lookup_string_in_fixed_set.cc
+++ b/net/base/lookup_string_in_fixed_set.cc
@@ -204,12 +204,12 @@
 int LookupSuffixInReversedSet(const unsigned char* graph,
                               size_t length,
                               bool include_private,
-                              base::StringPiece host,
+                              std::string_view host,
                               size_t* suffix_length) {
   FixedSetIncrementalLookup lookup(graph, length);
   *suffix_length = 0;
   int result = kDafsaNotFound;
-  base::StringPiece::const_iterator pos = host.end();
+  std::string_view::const_iterator pos = host.end();
   // Look up host from right to left.
   while (pos != host.begin() && lookup.Advance(*--pos)) {
     // Only host itself or a part that follows a dot can match.
diff --git a/net/base/lookup_string_in_fixed_set.h b/net/base/lookup_string_in_fixed_set.h
index a8184e69..47bdc11 100644
--- a/net/base/lookup_string_in_fixed_set.h
+++ b/net/base/lookup_string_in_fixed_set.h
@@ -7,7 +7,8 @@
 
 #include <stddef.h>
 
-#include "base/strings/string_piece.h"
+#include <string_view>
+
 #include "net/base/net_export.h"
 
 namespace net {
@@ -47,7 +48,7 @@
 int LookupSuffixInReversedSet(const unsigned char* graph,
                               size_t length,
                               bool include_private,
-                              base::StringPiece host,
+                              std::string_view host,
                               size_t* suffix_length);
 
 // FixedSetIncrementalLookup provides efficient membership and prefix queries
diff --git a/net/base/mime_sniffer.cc b/net/base/mime_sniffer.cc
index 826622c..1f7667e 100644
--- a/net/base/mime_sniffer.cc
+++ b/net/base/mime_sniffer.cc
@@ -103,13 +103,13 @@
 
 struct MagicNumber {
   const char* const mime_type;
-  const base::StringPiece magic;
+  const std::string_view magic;
   bool is_string;
   const char* const mask;  // if set, must have same length as |magic|
 };
 
 #define MAGIC_NUMBER(mime_type, magic) \
-  { (mime_type), base::StringPiece((magic), sizeof(magic) - 1), false, nullptr }
+  { (mime_type), std::string_view((magic), sizeof(magic) - 1), false, nullptr }
 
 template <int MagicSize, int MaskSize>
 class VerifySizes {
@@ -122,15 +122,15 @@
 #define verified_sizeof(magic, mask) \
 VerifySizes<sizeof(magic), sizeof(mask)>::SIZES
 
-#define MAGIC_MASK(mime_type, magic, mask)                                     \
-  {                                                                            \
-    (mime_type), base::StringPiece((magic), verified_sizeof(magic, mask) - 1), \
-        false, (mask)                                                          \
+#define MAGIC_MASK(mime_type, magic, mask)                                    \
+  {                                                                           \
+    (mime_type), std::string_view((magic), verified_sizeof(magic, mask) - 1), \
+        false, (mask)                                                         \
   }
 
 // Magic strings are case insensitive and must not include '\0' characters
 #define MAGIC_STRING(mime_type, magic) \
-  { (mime_type), base::StringPiece((magic), sizeof(magic) - 1), true, nullptr }
+  { (mime_type), std::string_view((magic), sizeof(magic) - 1), true, nullptr }
 
 static const MagicNumber kMagicNumbers[] = {
   // Source: HTML 5 specification
@@ -199,11 +199,11 @@
 
 struct OfficeExtensionType {
   OfficeDocType doc_type;
-  const base::StringPiece extension;
+  const std::string_view extension;
 };
 
 #define OFFICE_EXTENSION(type, extension) \
-  { (type), base::StringPiece((extension), sizeof(extension) - 1) }
+  { (type), std::string_view((extension), sizeof(extension) - 1) }
 
 static const OfficeExtensionType kOfficeExtensionTypes[] = {
   OFFICE_EXTENSION(DOC_TYPE_WORD, ".doc"),
@@ -284,7 +284,7 @@
 
 // Compare content header to a magic number where magic_entry can contain '.'
 // for single character of anything, allowing some bytes to be skipped.
-static bool MagicCmp(base::StringPiece content, base::StringPiece magic_entry) {
+static bool MagicCmp(std::string_view content, std::string_view magic_entry) {
   DCHECK_GE(content.length(), magic_entry.length());
 
   for (size_t i = 0; i < magic_entry.length(); ++i) {
@@ -296,9 +296,9 @@
 
 // Like MagicCmp() except that it ANDs each byte with a mask before
 // the comparison, because there are some bits we don't care about.
-static bool MagicMaskCmp(base::StringPiece content,
-                         base::StringPiece magic_entry,
-                         base::StringPiece magic_mask) {
+static bool MagicMaskCmp(std::string_view content,
+                         std::string_view magic_entry,
+                         std::string_view magic_mask) {
   DCHECK_GE(content.length(), magic_entry.length());
 
   for (size_t i = 0; i < magic_entry.length(); ++i) {
@@ -308,7 +308,7 @@
   return true;
 }
 
-static bool MatchMagicNumber(base::StringPiece content,
+static bool MatchMagicNumber(std::string_view content,
                              const MagicNumber& magic_entry,
                              std::string* result) {
   // Keep kBytesRequiredForMagic honest.
@@ -318,7 +318,7 @@
   if (content.length() >= magic_entry.magic.length()) {
     if (magic_entry.is_string) {
       // Consistency check - string entries should have no embedded nulls.
-      DCHECK_EQ(base::StringPiece::npos, magic_entry.magic.find('\0'));
+      DCHECK_EQ(std::string_view::npos, magic_entry.magic.find('\0'));
 
       // Do a case-insensitive prefix comparison.
       match = base::StartsWith(content, magic_entry.magic,
@@ -326,8 +326,7 @@
     } else if (!magic_entry.mask) {
       match = MagicCmp(content, magic_entry.magic);
     } else {
-      base::StringPiece magic_mask(magic_entry.mask,
-                                   magic_entry.magic.length());
+      std::string_view magic_mask(magic_entry.mask, magic_entry.magic.length());
       match = MagicMaskCmp(content, magic_entry.magic, magic_mask);
     }
   }
@@ -339,7 +338,7 @@
   return false;
 }
 
-static bool CheckForMagicNumbers(base::StringPiece content,
+static bool CheckForMagicNumbers(std::string_view content,
                                  base::span<const MagicNumber> magic_numbers,
                                  std::string* result) {
   for (const MagicNumber& magic : magic_numbers) {
@@ -352,7 +351,7 @@
 // Truncates |string_piece| to length |max_size| and returns true if
 // |string_piece| is now exactly |max_size|.
 static bool TruncateStringPiece(const size_t max_size,
-                                base::StringPiece* string_piece) {
+                                std::string_view* string_piece) {
   // Keep kMaxBytesToSniff honest.
   DCHECK_LE(static_cast<int>(max_size), kMaxBytesToSniff);
 
@@ -362,7 +361,7 @@
 
 // Returns true and sets result if the content appears to be HTML.
 // Clears have_enough_content if more data could possibly change the result.
-static bool SniffForHTML(base::StringPiece content,
+static bool SniffForHTML(std::string_view content,
                          bool* have_enough_content,
                          std::string* result) {
   // For HTML, we are willing to consider up to 512 bytes. This may be overly
@@ -371,7 +370,7 @@
 
   // We adopt a strategy similar to that used by Mozilla to sniff HTML tags,
   // but with some modifications to better match the HTML5 spec.
-  base::StringPiece trimmed =
+  std::string_view trimmed =
       base::TrimWhitespaceASCII(content, base::TRIM_LEADING);
 
   // |trimmed| now starts at first non-whitespace character (or is empty).
@@ -380,7 +379,7 @@
 
 // Returns true and sets result if the content matches any of kMagicNumbers.
 // Clears have_enough_content if more data could possibly change the result.
-static bool SniffForMagicNumbers(base::StringPiece content,
+static bool SniffForMagicNumbers(std::string_view content,
                                  bool* have_enough_content,
                                  std::string* result) {
   *have_enough_content &= TruncateStringPiece(kBytesRequiredForMagic, &content);
@@ -392,7 +391,7 @@
 // Returns true and sets result if the content matches any of
 // kOfficeMagicNumbers, and the URL has the proper extension.
 // Clears |have_enough_content| if more data could possibly change the result.
-static bool SniffForOfficeDocs(base::StringPiece content,
+static bool SniffForOfficeDocs(std::string_view content,
                                const GURL& url,
                                bool* have_enough_content,
                                std::string* result) {
@@ -405,7 +404,7 @@
     return false;
 
   OfficeDocType type = DOC_TYPE_NONE;
-  base::StringPiece url_path = url.path_piece();
+  std::string_view url_path = url.path_piece();
   for (const auto& office_extension : kOfficeExtensionTypes) {
     if (base::EndsWith(url_path, office_extension.extension,
                        base::CompareCase::INSENSITIVE_ASCII)) {
@@ -485,7 +484,7 @@
 //
 // Returns false if additional data is required to determine the file type, or
 // true if there is enough data to make a decision.
-static bool SniffForInvalidOfficeDocs(base::StringPiece content,
+static bool SniffForInvalidOfficeDocs(std::string_view content,
                                       const GURL& url,
                                       std::string* result) {
   if (!TruncateStringPiece(kBytesRequiredForOfficeMagic, &content))
@@ -517,7 +516,7 @@
 // while HTML5 has a different recommendation -- what should we do?
 // TODO(evanm): this is incorrect for documents whose encoding isn't a superset
 // of ASCII -- do we care?
-static bool SniffXML(base::StringPiece content,
+static bool SniffXML(std::string_view content,
                      bool* have_enough_content,
                      std::string* result) {
   // We allow at most 300 bytes of content before we expect the opening tag.
@@ -531,14 +530,15 @@
   size_t pos = 0;
   for (size_t i = 0; i < kMaxTagIterations && pos < content.length(); ++i) {
     pos = content.find('<', pos);
-    if (pos == base::StringPiece::npos)
+    if (pos == std::string_view::npos) {
       return false;
+    }
 
-    base::StringPiece current = content.substr(pos);
+    std::string_view current = content.substr(pos);
 
     // Skip XML and DOCTYPE declarations.
-    static constexpr base::StringPiece kXmlPrefix("<?xml");
-    static constexpr base::StringPiece kDocTypePrefix("<!DOCTYPE");
+    static constexpr std::string_view kXmlPrefix("<?xml");
+    static constexpr std::string_view kDocTypePrefix("<!DOCTYPE");
     if (base::StartsWith(current, kXmlPrefix,
                          base::CompareCase::INSENSITIVE_ASCII) ||
         base::StartsWith(current, kDocTypePrefix,
@@ -574,7 +574,7 @@
 // Returns true and sets result to "application/octet-stream" if the content
 // appears to be binary data. Otherwise, returns false and sets "text/plain".
 // Clears have_enough_content if more data could possibly change the result.
-static bool SniffBinary(base::StringPiece content,
+static bool SniffBinary(std::string_view content,
                         bool* have_enough_content,
                         std::string* result) {
   // There is no consensus about exactly how to sniff for binary content.
@@ -608,7 +608,7 @@
   return false;
 }
 
-static bool IsUnknownMimeType(base::StringPiece mime_type) {
+static bool IsUnknownMimeType(std::string_view mime_type) {
   // TODO(tc): Maybe reuse some code in net/http/http_response_headers.* here.
   // If we do, please be careful not to alter the semantics at all.
   static const char* const kUnknownMimeTypes[] = {
@@ -625,7 +625,7 @@
     if (mime_type == unknown_mime_type)
       return true;
   }
-  if (mime_type.find('/') == base::StringPiece::npos) {
+  if (mime_type.find('/') == std::string_view::npos) {
     // Firefox rejects a mime type if it does not contain a slash
     return true;
   }
@@ -635,7 +635,7 @@
 // Returns true and sets result if the content appears to be a crx (Chrome
 // extension) file.
 // Clears have_enough_content if more data could possibly change the result.
-static bool SniffCRX(base::StringPiece content,
+static bool SniffCRX(std::string_view content,
                      const GURL& url,
                      bool* have_enough_content,
                      std::string* result) {
@@ -655,7 +655,7 @@
   return CheckForMagicNumbers(content, kCRXMagicNumbers, result);
 }
 
-bool ShouldSniffMimeType(const GURL& url, base::StringPiece mime_type) {
+bool ShouldSniffMimeType(const GURL& url, std::string_view mime_type) {
   bool sniffable_scheme = url.is_empty() || url.SchemeIsHTTPOrHTTPS() ||
 #if BUILDFLAG(IS_ANDROID)
                           url.SchemeIs("content") ||
@@ -703,7 +703,7 @@
   return false;
 }
 
-bool SniffMimeType(base::StringPiece content,
+bool SniffMimeType(std::string_view content,
                    const GURL& url,
                    const std::string& type_hint,
                    ForceSniffFileUrlsForHtml force_sniff_file_url_for_html,
@@ -793,8 +793,7 @@
   return have_enough_content;
 }
 
-bool SniffMimeTypeFromLocalData(base::StringPiece content,
-                                std::string* result) {
+bool SniffMimeTypeFromLocalData(std::string_view content, std::string* result) {
   // First check the extra table.
   if (CheckForMagicNumbers(content, kExtraMagicNumbers, result))
     return true;
@@ -802,7 +801,7 @@
   return CheckForMagicNumbers(content, kMagicNumbers, result);
 }
 
-bool LooksLikeBinary(base::StringPiece content) {
+bool LooksLikeBinary(std::string_view content) {
   // The definition of "binary bytes" is from the spec at
   // https://mimesniff.spec.whatwg.org/#binary-data-byte
   //
diff --git a/net/base/mime_sniffer.h b/net/base/mime_sniffer.h
index b323cb3..1a8ed88 100644
--- a/net/base/mime_sniffer.h
+++ b/net/base/mime_sniffer.h
@@ -8,8 +8,8 @@
 #include <stddef.h>
 
 #include <string>
+#include <string_view>
 
-#include "base/strings/string_piece.h"
 #include "net/base/net_export.h"
 
 class GURL;
@@ -36,7 +36,7 @@
 // |mime_type| is the current mime type, e.g. from the Content-Type header.
 // Returns true if the mime type should be sniffed.
 NET_EXPORT bool ShouldSniffMimeType(const GURL& url,
-                                    base::StringPiece mime_type);
+                                    std::string_view mime_type);
 
 // Guess a mime type from the first few bytes of content an its URL.  Always
 // assigns |result| with its best guess of a mime type.
@@ -53,7 +53,7 @@
 // |result| will be populated with a putative MIME type, but the method should
 // be called again with more of the content.
 NET_EXPORT bool SniffMimeType(
-    base::StringPiece content,
+    std::string_view content,
     const GURL& url,
     const std::string& type_hint,
     ForceSniffFileUrlsForHtml force_sniff_file_url_for_html,
@@ -70,12 +70,12 @@
 // |content| contains the bytes to sniff.
 // |result| is address at which to place the sniffed mime type.
 // Returns true if a MIME type match was found.
-NET_EXPORT bool SniffMimeTypeFromLocalData(base::StringPiece content,
+NET_EXPORT bool SniffMimeTypeFromLocalData(std::string_view content,
                                            std::string* result);
 
 // Returns true if |content| contains bytes that are control codes that do
 // not usually appear in plain text.
-NET_EXPORT_PRIVATE bool LooksLikeBinary(base::StringPiece content);
+NET_EXPORT_PRIVATE bool LooksLikeBinary(std::string_view content);
 
 }  // namespace net
 
diff --git a/net/base/mime_sniffer_unittest.cc b/net/base/mime_sniffer_unittest.cc
index ebd0e02..ff694d4 100644
--- a/net/base/mime_sniffer_unittest.cc
+++ b/net/base/mime_sniffer_unittest.cc
@@ -24,7 +24,7 @@
   return std::string(str, N - 1);
 }
 
-static std::string SniffMimeType(base::StringPiece content,
+static std::string SniffMimeType(std::string_view content,
                                  const std::string& url,
                                  const std::string& mime_type_hint) {
   std::string mime_type;
@@ -74,13 +74,13 @@
 
   GURL url;
 
-  SniffMimeType(base::StringPiece(), url, type_hint,
+  SniffMimeType(std::string_view(), url, type_hint,
                 ForceSniffFileUrlsForHtml::kDisabled, &mime_type);
   EXPECT_EQ("text/plain", mime_type);
-  SniffMimeType(base::StringPiece(buf, 1), url, type_hint,
+  SniffMimeType(std::string_view(buf, 1), url, type_hint,
                 ForceSniffFileUrlsForHtml::kDisabled, &mime_type);
   EXPECT_EQ("text/plain", mime_type);
-  SniffMimeType(base::StringPiece(buf, 2), url, type_hint,
+  SniffMimeType(std::string_view(buf, 2), url, type_hint,
                 ForceSniffFileUrlsForHtml::kDisabled, &mime_type);
   EXPECT_EQ("application/octet-stream", mime_type);
 }
@@ -448,26 +448,26 @@
   std::string mime_type;
   const char kOggTestData[] = "OggS\x00";
   EXPECT_TRUE(SniffMimeTypeFromLocalData(
-      base::StringPiece(kOggTestData, sizeof(kOggTestData) - 1), &mime_type));
+      std::string_view(kOggTestData, sizeof(kOggTestData) - 1), &mime_type));
   EXPECT_EQ("audio/ogg", mime_type);
   mime_type.clear();
   // Check ogg header requires the terminal '\0' to be sniffed.
   EXPECT_FALSE(SniffMimeTypeFromLocalData(
-      base::StringPiece(kOggTestData, sizeof(kOggTestData) - 2), &mime_type));
+      std::string_view(kOggTestData, sizeof(kOggTestData) - 2), &mime_type));
   EXPECT_EQ("", mime_type);
   mime_type.clear();
 
   const char kFlacTestData[] =
       "fLaC\x00\x00\x00\x22\x12\x00\x12\x00\x00\x00\x00\x00";
   EXPECT_TRUE(SniffMimeTypeFromLocalData(
-      base::StringPiece(kFlacTestData, sizeof(kFlacTestData) - 1), &mime_type));
+      std::string_view(kFlacTestData, sizeof(kFlacTestData) - 1), &mime_type));
   EXPECT_EQ("audio/x-flac", mime_type);
   mime_type.clear();
 
   const char kWMATestData[] =
       "\x30\x26\xb2\x75\x8e\x66\xcf\x11\xa6\xd9\x00\xaa\x00\x62\xce\x6c";
   EXPECT_TRUE(SniffMimeTypeFromLocalData(
-      base::StringPiece(kWMATestData, sizeof(kWMATestData) - 1), &mime_type));
+      std::string_view(kWMATestData, sizeof(kWMATestData) - 1), &mime_type));
   EXPECT_EQ("video/x-ms-asf", mime_type);
   mime_type.clear();
 
@@ -476,21 +476,21 @@
   const char kMP4TestData[] =
       "\x00\x00\x00\x20\x66\x74\x79\x70\x4d\x34\x41\x20\x00\x00\x00\x00";
   EXPECT_TRUE(SniffMimeTypeFromLocalData(
-      base::StringPiece(kMP4TestData, sizeof(kMP4TestData) - 1), &mime_type));
+      std::string_view(kMP4TestData, sizeof(kMP4TestData) - 1), &mime_type));
   EXPECT_EQ("video/mp4", mime_type);
   mime_type.clear();
 
   const char kAACTestData[] =
       "\xff\xf1\x50\x80\x02\x20\xb0\x23\x0a\x83\x20\x7d\x61\x90\x3e\xb1";
   EXPECT_TRUE(SniffMimeTypeFromLocalData(
-      base::StringPiece(kAACTestData, sizeof(kAACTestData) - 1), &mime_type));
+      std::string_view(kAACTestData, sizeof(kAACTestData) - 1), &mime_type));
   EXPECT_EQ("audio/mpeg", mime_type);
   mime_type.clear();
 
   const char kAMRTestData[] =
       "\x23\x21\x41\x4d\x52\x0a\x3c\x53\x0a\x7c\xe8\xb8\x41\xa5\x80\xca";
   EXPECT_TRUE(SniffMimeTypeFromLocalData(
-      base::StringPiece(kAMRTestData, sizeof(kAMRTestData) - 1), &mime_type));
+      std::string_view(kAMRTestData, sizeof(kAMRTestData) - 1), &mime_type));
   EXPECT_EQ("audio/amr", mime_type);
   mime_type.clear();
 }
@@ -499,21 +499,21 @@
   std::string mime_type;
   const char kWebPSimpleFormat[] = "RIFF\xee\x81\x00\x00WEBPVP8 ";
   EXPECT_TRUE(SniffMimeTypeFromLocalData(
-      base::StringPiece(kWebPSimpleFormat, sizeof(kWebPSimpleFormat) - 1),
+      std::string_view(kWebPSimpleFormat, sizeof(kWebPSimpleFormat) - 1),
       &mime_type));
   EXPECT_EQ("image/webp", mime_type);
   mime_type.clear();
 
   const char kWebPLosslessFormat[] = "RIFF\xee\x81\x00\x00WEBPVP8L";
   EXPECT_TRUE(SniffMimeTypeFromLocalData(
-      base::StringPiece(kWebPLosslessFormat, sizeof(kWebPLosslessFormat) - 1),
+      std::string_view(kWebPLosslessFormat, sizeof(kWebPLosslessFormat) - 1),
       &mime_type));
   EXPECT_EQ("image/webp", mime_type);
   mime_type.clear();
 
   const char kWebPExtendedFormat[] = "RIFF\xee\x81\x00\x00WEBPVP8X";
   EXPECT_TRUE(SniffMimeTypeFromLocalData(
-      base::StringPiece(kWebPExtendedFormat, sizeof(kWebPExtendedFormat) - 1),
+      std::string_view(kWebPExtendedFormat, sizeof(kWebPExtendedFormat) - 1),
       &mime_type));
   EXPECT_EQ("image/webp", mime_type);
   mime_type.clear();
diff --git a/net/base/mime_util.cc b/net/base/mime_util.cc
index d4ac4b8..0f20772 100644
--- a/net/base/mime_util.cc
+++ b/net/base/mime_util.cc
@@ -2,10 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "net/base/mime_util.h"
+
 #include <algorithm>
 #include <iterator>
 #include <map>
 #include <string>
+#include <string_view>
 #include <unordered_set>
 
 #include "base/base64.h"
@@ -14,12 +17,10 @@
 #include "base/lazy_instance.h"
 #include "base/rand_util.h"
 #include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
-#include "net/base/mime_util.h"
 #include "net/base/platform_mime_util.h"
 #include "net/http/http_util.h"
 
@@ -46,7 +47,7 @@
   bool MatchesMimeType(const std::string& mime_type_pattern,
                        const std::string& mime_type) const;
 
-  bool ParseMimeTypeWithoutParameter(base::StringPiece type_string,
+  bool ParseMimeTypeWithoutParameter(std::string_view type_string,
                                      std::string* top_level_type,
                                      std::string* subtype) const;
 
@@ -247,7 +248,7 @@
       // including uninitialized memory if ext is longer than extensions.
       if (end_pos == ext.size() &&
           base::EqualsCaseInsensitiveASCII(
-              base::StringPiece(extensions, ext.size()), ext)) {
+              std::string_view(extensions, ext.size()), ext)) {
         return mapping.mime_type;
       }
       extensions += end_pos;
@@ -260,7 +261,7 @@
 }
 
 static base::FilePath::StringType StringToFilePathStringType(
-    base::StringPiece string_piece) {
+    std::string_view string_piece) {
 #if BUILDFLAG(IS_WIN)
   return base::UTF8ToWide(string_piece);
 #else
@@ -284,7 +285,7 @@
       const char* extension_end = strchr(extensions, ',');
       size_t len =
           extension_end ? extension_end - extensions : strlen(extensions);
-      *result = StringToFilePathStringType(base::StringPiece(extensions, len));
+      *result = StringToFilePathStringType(std::string_view(extensions, len));
       return true;
     }
   }
@@ -451,9 +452,9 @@
   if (base_type.length() < base_pattern.length() - 1)
     return false;
 
-  base::StringPiece base_pattern_piece(base_pattern);
-  base::StringPiece left(base_pattern_piece.substr(0, star));
-  base::StringPiece right(base_pattern_piece.substr(star + 1));
+  std::string_view base_pattern_piece(base_pattern);
+  std::string_view left(base_pattern_piece.substr(0, star));
+  std::string_view right(base_pattern_piece.substr(star + 1));
 
   if (!base::StartsWith(base_type, left, base::CompareCase::INSENSITIVE_ASCII))
     return false;
@@ -576,10 +577,10 @@
   return true;
 }
 
-bool MimeUtil::ParseMimeTypeWithoutParameter(base::StringPiece type_string,
+bool MimeUtil::ParseMimeTypeWithoutParameter(std::string_view type_string,
                                              std::string* top_level_type,
                                              std::string* subtype) const {
-  std::vector<base::StringPiece> components = base::SplitStringPiece(
+  std::vector<std::string_view> components = base::SplitStringPiece(
       type_string, "/", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
   if (components.size() != 2)
     return false;
@@ -645,7 +646,7 @@
   return g_mime_util.Get().MatchesMimeType(mime_type_pattern, mime_type);
 }
 
-bool ParseMimeTypeWithoutParameter(base::StringPiece type_string,
+bool ParseMimeTypeWithoutParameter(std::string_view type_string,
                                    std::string* top_level_type,
                                    std::string* subtype) {
   return g_mime_util.Get().ParseMimeTypeWithoutParameter(
@@ -752,12 +753,12 @@
     bool prefix_match,
     std::unordered_set<base::FilePath::StringType>* extensions) {
   for (const auto& mapping : mappings) {
-    base::StringPiece cur_mime_type(mapping.mime_type);
+    std::string_view cur_mime_type(mapping.mime_type);
 
     if (base::StartsWith(cur_mime_type, mime_type,
                          base::CompareCase::INSENSITIVE_ASCII) &&
         (prefix_match || (cur_mime_type.length() == mime_type.length()))) {
-      for (base::StringPiece this_extension : base::SplitStringPiece(
+      for (std::string_view this_extension : base::SplitStringPiece(
                mapping.extensions, ",", base::TRIM_WHITESPACE,
                base::SPLIT_WANT_ALL)) {
         extensions->insert(StringToFilePathStringType(this_extension));
@@ -803,7 +804,7 @@
 // following characters are legal for boundaries:  '()+_,-./:=?
 // However the following characters, though legal, cause some sites
 // to fail: (),./:=+
-constexpr base::StringPiece kMimeBoundaryCharacters(
+constexpr std::string_view kMimeBoundaryCharacters(
     "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
 
 // Size of mime multipart boundary.
@@ -934,7 +935,7 @@
 
 // TODO(toyoshim): We may prefer to implement a strict RFC2616 media-type
 // (https://tools.ietf.org/html/rfc2616#section-3.7) parser.
-absl::optional<std::string> ExtractMimeTypeFromMediaType(
+std::optional<std::string> ExtractMimeTypeFromMediaType(
     const std::string& type_string,
     bool accept_comma_separated) {
   std::string::size_type end = type_string.find(';');
@@ -947,7 +948,7 @@
                                     &subtype)) {
     return top_level_type + "/" + subtype;
   }
-  return absl::nullopt;
+  return std::nullopt;
 }
 
 }  // namespace net
diff --git a/net/base/mime_util.h b/net/base/mime_util.h
index 419934c..8c0980cf 100644
--- a/net/base/mime_util.h
+++ b/net/base/mime_util.h
@@ -19,14 +19,14 @@
 
 #include <stddef.h>
 
+#include <optional>
 #include <string>
+#include <string_view>
 #include <vector>
 
 #include "base/files/file_path.h"
-#include "base/strings/string_piece.h"
 #include "base/strings/string_split.h"
 #include "net/base/net_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -84,11 +84,11 @@
 //
 // This function strips leading and trailing whitespace from the MIME type.
 // TODO: investigate if we should strip strictly HTTP whitespace.
-NET_EXPORT bool ParseMimeTypeWithoutParameter(base::StringPiece type_string,
+NET_EXPORT bool ParseMimeTypeWithoutParameter(std::string_view type_string,
                                               std::string* top_level_type,
                                               std::string* subtype);
 
-// Returns `absl::optional` with value containing the extracted `type/sub_type`
+// Returns `std::optional` with value containing the extracted `type/sub_type`
 // if `type_string` is a correctly-formed mime type specifier. Returns optional
 // with empty otherwise.
 // Set `accept_comma_separated` to accept a type_string like "text/html,
@@ -102,7 +102,7 @@
 // While RFC 2616 does not allow it, other browsers allow multiple values in
 // the HTTP media type header field, Content-Type. In such cases, the media
 // type passed here may contain the multiple values separated by commas.
-NET_EXPORT absl::optional<std::string> ExtractMimeTypeFromMediaType(
+NET_EXPORT std::optional<std::string> ExtractMimeTypeFromMediaType(
     const std::string& type_string,
     bool accept_comma_separated);
 
diff --git a/net/base/mime_util_unittest.cc b/net/base/mime_util_unittest.cc
index 355e8d33..9accf9ea 100644
--- a/net/base/mime_util_unittest.cc
+++ b/net/base/mime_util_unittest.cc
@@ -419,7 +419,7 @@
 
 TEST_P(ExtractMIMETypeTestInvalid, MustFail) {
   // Parsing is expected to fail.
-  EXPECT_EQ(absl::nullopt, net::ExtractMimeTypeFromMediaType(GetParam(), true));
+  EXPECT_EQ(std::nullopt, net::ExtractMimeTypeFromMediaType(GetParam(), true));
 }
 
 class ExtractMIMETypeTestValid : public testing::TestWithParam<std::string> {};
diff --git a/net/base/net_string_util.h b/net/base/net_string_util.h
index cb45561..e65baca 100644
--- a/net/base/net_string_util.h
+++ b/net/base/net_string_util.h
@@ -19,31 +19,31 @@
 
 // Converts |text| using |charset| to UTF-8, and writes it to |output|.
 // On failure, returns false and |output| is cleared.
-bool ConvertToUtf8(base::StringPiece text,
+bool ConvertToUtf8(std::string_view text,
                    const char* charset,
                    std::string* output);
 
 // Converts |text| using |charset| to UTF-8, normalizes the result, and writes
 // it to |output|.  On failure, returns false and |output| is cleared.
-bool ConvertToUtf8AndNormalize(base::StringPiece text,
+bool ConvertToUtf8AndNormalize(std::string_view text,
                                const char* charset,
                                std::string* output);
 
 // Converts |text| using |charset| to UTF-16, and writes it to |output|.
 // On failure, returns false and |output| is cleared.
-bool ConvertToUTF16(base::StringPiece text,
+bool ConvertToUTF16(std::string_view text,
                     const char* charset,
                     std::u16string* output);
 
 // Converts |text| using |charset| to UTF-16, and writes it to |output|.
 // Any characters that can not be converted are replaced with U+FFFD.
-bool ConvertToUTF16WithSubstitutions(base::StringPiece text,
+bool ConvertToUTF16WithSubstitutions(std::string_view text,
                                      const char* charset,
                                      std::u16string* output);
 
 // Converts |str| to uppercase using the default locale, and writes it to
 // |output|. On failure returns false and |output| is cleared.
-NET_EXPORT_PRIVATE bool ToUpper(base::StringPiece16 str,
+NET_EXPORT_PRIVATE bool ToUpper(std::u16string_view str,
                                 std::u16string* output);
 
 }  // namespace net
diff --git a/net/base/net_string_util_icu.cc b/net/base/net_string_util_icu.cc
index 67dcd9c..12c42be 100644
--- a/net/base/net_string_util_icu.cc
+++ b/net/base/net_string_util_icu.cc
@@ -4,10 +4,11 @@
 
 #include "net/base/net_string_util.h"
 
+#include <string_view>
+
 #include "base/i18n/case_conversion.h"
 #include "base/i18n/i18n_constants.h"
 #include "base/i18n/icu_string_conversions.h"
-#include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "third_party/icu/source/common/unicode/ucnv.h"
 
@@ -15,7 +16,7 @@
 
 const char* const kCharsetLatin1 = base::kCodepageLatin1;
 
-bool ConvertToUtf8(base::StringPiece text,
+bool ConvertToUtf8(std::string_view text,
                    const char* charset,
                    std::string* output) {
   output->clear();
@@ -43,27 +44,27 @@
   return true;
 }
 
-bool ConvertToUtf8AndNormalize(base::StringPiece text,
+bool ConvertToUtf8AndNormalize(std::string_view text,
                                const char* charset,
                                std::string* output) {
   return base::ConvertToUtf8AndNormalize(text, charset, output);
 }
 
-bool ConvertToUTF16(base::StringPiece text,
+bool ConvertToUTF16(std::string_view text,
                     const char* charset,
                     std::u16string* output) {
   return base::CodepageToUTF16(text, charset,
                                base::OnStringConversionError::FAIL, output);
 }
 
-bool ConvertToUTF16WithSubstitutions(base::StringPiece text,
+bool ConvertToUTF16WithSubstitutions(std::string_view text,
                                      const char* charset,
                                      std::u16string* output) {
   return base::CodepageToUTF16(
       text, charset, base::OnStringConversionError::SUBSTITUTE, output);
 }
 
-bool ToUpper(base::StringPiece16 str, std::u16string* output) {
+bool ToUpper(std::u16string_view str, std::u16string* output) {
   *output = base::i18n::ToUpper(str);
   return true;
 }
diff --git a/net/base/net_string_util_icu_alternatives_android.cc b/net/base/net_string_util_icu_alternatives_android.cc
index b18e0093..48287a3 100644
--- a/net/base/net_string_util_icu_alternatives_android.cc
+++ b/net/base/net_string_util_icu_alternatives_android.cc
@@ -3,10 +3,10 @@
 // found in the LICENSE file.
 
 #include <string>
+#include <string_view>
 
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
-#include "base/strings/string_piece.h"
 #include "net/base/net_string_util.h"
 #include "net/net_jni_headers/NetStringUtil_jni.h"
 
@@ -18,7 +18,7 @@
 
 // Attempts to convert |text| encoded in |charset| to a jstring (Java unicode
 // string).  Returns the result jstring, or NULL on failure.
-ScopedJavaLocalRef<jstring> ConvertToJstring(base::StringPiece text,
+ScopedJavaLocalRef<jstring> ConvertToJstring(std::string_view text,
                                              const char* charset) {
   JNIEnv* env = base::android::AttachCurrentThread();
   ScopedJavaLocalRef<jobject> java_byte_buffer(
@@ -26,7 +26,7 @@
       env->NewDirectByteBuffer(const_cast<char*>(text.data()), text.length()));
   base::android::CheckException(env);
   base::android::ScopedJavaLocalRef<jstring> java_charset =
-      base::android::ConvertUTF8ToJavaString(env, base::StringPiece(charset));
+      base::android::ConvertUTF8ToJavaString(env, std::string_view(charset));
   ScopedJavaLocalRef<jstring> java_result =
       android::Java_NetStringUtil_convertToUnicode(env, java_byte_buffer,
                                                    java_charset);
@@ -36,7 +36,7 @@
 // Attempts to convert |text| encoded in |charset| to a jstring (Java unicode
 // string) and then normalizes the string.  Returns the result jstring, or NULL
 // on failure.
-ScopedJavaLocalRef<jstring> ConvertToNormalizedJstring(base::StringPiece text,
+ScopedJavaLocalRef<jstring> ConvertToNormalizedJstring(std::string_view text,
                                                        const char* charset) {
   JNIEnv* env = base::android::AttachCurrentThread();
   ScopedJavaLocalRef<jobject> java_byte_buffer(
@@ -44,7 +44,7 @@
       env->NewDirectByteBuffer(const_cast<char*>(text.data()), text.length()));
   base::android::CheckException(env);
   base::android::ScopedJavaLocalRef<jstring> java_charset =
-      base::android::ConvertUTF8ToJavaString(env, base::StringPiece(charset));
+      base::android::ConvertUTF8ToJavaString(env, std::string_view(charset));
   ScopedJavaLocalRef<jstring> java_result =
       android::Java_NetStringUtil_convertToUnicodeAndNormalize(
           env, java_byte_buffer, java_charset);
@@ -54,7 +54,7 @@
 // Converts |text| encoded in |charset| to a jstring (Java unicode string).
 // Any characters that can not be converted are replaced with U+FFFD.
 ScopedJavaLocalRef<jstring> ConvertToJstringWithSubstitutions(
-    base::StringPiece text,
+    std::string_view text,
     const char* charset) {
   JNIEnv* env = base::android::AttachCurrentThread();
   ScopedJavaLocalRef<jobject> java_byte_buffer(
@@ -62,7 +62,7 @@
       env->NewDirectByteBuffer(const_cast<char*>(text.data()), text.length()));
   base::android::CheckException(env);
   base::android::ScopedJavaLocalRef<jstring> java_charset =
-      base::android::ConvertUTF8ToJavaString(env, base::StringPiece(charset));
+      base::android::ConvertUTF8ToJavaString(env, std::string_view(charset));
   ScopedJavaLocalRef<jstring> java_result =
       android::Java_NetStringUtil_convertToUnicodeWithSubstitutions(
           env, java_byte_buffer, java_charset);
@@ -75,7 +75,7 @@
 // by base::kCodepageLatin1 (which is const char[]) in net_string_util_icu.cc.
 const char* const kCharsetLatin1 = "ISO-8859-1";
 
-bool ConvertToUtf8(base::StringPiece text,
+bool ConvertToUtf8(std::string_view text,
                    const char* charset,
                    std::string* output) {
   output->clear();
@@ -86,7 +86,7 @@
   return true;
 }
 
-bool ConvertToUtf8AndNormalize(base::StringPiece text,
+bool ConvertToUtf8AndNormalize(std::string_view text,
                                const char* charset,
                                std::string* output) {
   output->clear();
@@ -98,7 +98,7 @@
   return true;
 }
 
-bool ConvertToUTF16(base::StringPiece text,
+bool ConvertToUTF16(std::string_view text,
                     const char* charset,
                     std::u16string* output) {
   output->clear();
@@ -109,7 +109,7 @@
   return true;
 }
 
-bool ConvertToUTF16WithSubstitutions(base::StringPiece text,
+bool ConvertToUTF16WithSubstitutions(std::string_view text,
                                      const char* charset,
                                      std::u16string* output) {
   output->clear();
@@ -121,7 +121,7 @@
   return true;
 }
 
-bool ToUpper(base::StringPiece16 str, std::u16string* output) {
+bool ToUpper(std::u16string_view str, std::u16string* output) {
   output->clear();
   JNIEnv* env = base::android::AttachCurrentThread();
   ScopedJavaLocalRef<jstring> java_new_str(
diff --git a/net/base/net_string_util_icu_alternatives_ios.mm b/net/base/net_string_util_icu_alternatives_ios.mm
index 725b7ffa..0527191 100644
--- a/net/base/net_string_util_icu_alternatives_ios.mm
+++ b/net/base/net_string_util_icu_alternatives_ios.mm
@@ -6,11 +6,11 @@
 
 #include <ostream>
 #include <string>
+#include <string_view>
 
 #include "base/apple/scoped_cftyperef.h"
 #include "base/check.h"
 #include "base/numerics/safe_conversions.h"
-#include "base/strings/string_piece.h"
 #include "base/strings/sys_string_conversions.h"
 #include "net/base/net_string_util.h"
 
@@ -37,7 +37,7 @@
 // by base::kCodepageLatin1 (which is const char[]) in net_string_util_icu.cc.
 const char* const kCharsetLatin1 = "ISO-8859-1";
 
-bool ConvertToUtf8(base::StringPiece text,
+bool ConvertToUtf8(std::string_view text,
                    const char* charset,
                    std::string* output) {
   CFStringEncoding encoding;
@@ -55,28 +55,28 @@
   return true;
 }
 
-bool ConvertToUtf8AndNormalize(base::StringPiece text,
+bool ConvertToUtf8AndNormalize(std::string_view text,
                                const char* charset,
                                std::string* output) {
   DCHECK(false) << "Not implemented yet.";
   return false;
 }
 
-bool ConvertToUTF16(base::StringPiece text,
+bool ConvertToUTF16(std::string_view text,
                     const char* charset,
                     std::u16string* output) {
   DCHECK(false) << "Not implemented yet.";
   return false;
 }
 
-bool ConvertToUTF16WithSubstitutions(base::StringPiece text,
+bool ConvertToUTF16WithSubstitutions(std::string_view text,
                                      const char* charset,
                                      std::u16string* output) {
   DCHECK(false) << "Not implemented yet.";
   return false;
 }
 
-bool ToUpper(base::StringPiece16 str, std::u16string* output) {
+bool ToUpper(std::u16string_view str, std::u16string* output) {
   base::apple::ScopedCFTypeRef<CFStringRef> cfstring =
       base::SysUTF16ToCFStringRef(str);
   base::apple::ScopedCFTypeRef<CFMutableStringRef> mutable_cfstring(
diff --git a/net/base/network_anonymization_key.cc b/net/base/network_anonymization_key.cc
index 13d5097..f1e495d4 100644
--- a/net/base/network_anonymization_key.cc
+++ b/net/base/network_anonymization_key.cc
@@ -3,6 +3,8 @@
 // found in the LICENSE file.
 #include "net/base/network_anonymization_key.h"
 
+#include <optional>
+
 #include "base/feature_list.h"
 #include "base/unguessable_token.h"
 #include "base/values.h"
@@ -11,7 +13,6 @@
 #include "net/base/network_isolation_key.h"
 #include "net/base/schemeful_site.h"
 #include "net/cookies/site_for_cookies.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -30,7 +31,7 @@
 NetworkAnonymizationKey::NetworkAnonymizationKey(
     const SchemefulSite& top_frame_site,
     bool is_cross_site,
-    absl::optional<base::UnguessableToken> nonce)
+    std::optional<base::UnguessableToken> nonce)
     : top_frame_site_(top_frame_site),
       is_cross_site_(is_cross_site),
       nonce_(nonce) {
@@ -40,7 +41,7 @@
 NetworkAnonymizationKey NetworkAnonymizationKey::CreateFromFrameSite(
     const SchemefulSite& top_frame_site,
     const SchemefulSite& frame_site,
-    absl::optional<base::UnguessableToken> nonce) {
+    std::optional<base::UnguessableToken> nonce) {
   bool is_cross_site = top_frame_site != frame_site;
   return NetworkAnonymizationKey(top_frame_site, is_cross_site, nonce);
 }
@@ -63,9 +64,9 @@
 }
 
 NetworkAnonymizationKey::NetworkAnonymizationKey()
-    : top_frame_site_(absl::nullopt),
+    : top_frame_site_(std::nullopt),
       is_cross_site_(false),
-      nonce_(absl::nullopt) {}
+      nonce_(std::nullopt) {}
 
 NetworkAnonymizationKey::NetworkAnonymizationKey(
     const NetworkAnonymizationKey& network_anonymization_key) = default;
@@ -128,7 +129,7 @@
   if (IsTransient())
     return false;
 
-  absl::optional<std::string> top_frame_value =
+  std::optional<std::string> top_frame_value =
       SerializeSiteWithNonce(*top_frame_site_);
   if (!top_frame_value)
     return false;
@@ -160,7 +161,7 @@
   }
 
   // Check top_level_site is valid for any key scheme
-  absl::optional<SchemefulSite> top_frame_site =
+  std::optional<SchemefulSite> top_frame_site =
       SchemefulSite::DeserializeWithNonce(
           base::PassKey<NetworkAnonymizationKey>(), list[0].GetString());
   if (!top_frame_site) {
@@ -175,11 +176,11 @@
 }
 
 std::string NetworkAnonymizationKey::GetSiteDebugString(
-    const absl::optional<SchemefulSite>& site) const {
+    const std::optional<SchemefulSite>& site) const {
   return site ? site->GetDebugString() : "null";
 }
 
-absl::optional<std::string> NetworkAnonymizationKey::SerializeSiteWithNonce(
+std::optional<std::string> NetworkAnonymizationKey::SerializeSiteWithNonce(
     const SchemefulSite& site) {
   return *(const_cast<SchemefulSite&>(site).SerializeWithNonce(
       base::PassKey<NetworkAnonymizationKey>()));
diff --git a/net/base/network_anonymization_key.h b/net/base/network_anonymization_key.h
index c8ddaa8..be091f9 100644
--- a/net/base/network_anonymization_key.h
+++ b/net/base/network_anonymization_key.h
@@ -6,6 +6,7 @@
 #define NET_BASE_NETWORK_ANONYMIZATION_KEY_H_
 
 #include <cstddef>
+#include <optional>
 #include <string>
 #include <tuple>
 
@@ -13,7 +14,6 @@
 #include "net/base/net_export.h"
 #include "net/base/network_isolation_key.h"
 #include "net/base/schemeful_site.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
 class Value;
@@ -91,14 +91,14 @@
   // same-site (see comment on the class, above) and has no nonce.
   static NetworkAnonymizationKey CreateSameSite(
       const SchemefulSite& top_frame_site) {
-    return NetworkAnonymizationKey(top_frame_site, false, absl::nullopt);
+    return NetworkAnonymizationKey(top_frame_site, false, std::nullopt);
   }
 
   // Create a `NetworkAnonymizationKey` from a `top_frame_site`, assuming it is
   // cross-site (see comment on the class, above) and has no nonce.
   static NetworkAnonymizationKey CreateCrossSite(
       const SchemefulSite& top_frame_site) {
-    return NetworkAnonymizationKey(top_frame_site, true, absl::nullopt);
+    return NetworkAnonymizationKey(top_frame_site, true, std::nullopt);
   }
 
   // Create a `NetworkAnonymizationKey` from a `top_frame_site` and
@@ -107,7 +107,7 @@
   static NetworkAnonymizationKey CreateFromFrameSite(
       const SchemefulSite& top_frame_site,
       const SchemefulSite& frame_site,
-      absl::optional<base::UnguessableToken> nonce = absl::nullopt);
+      std::optional<base::UnguessableToken> nonce = std::nullopt);
 
   // Creates a `NetworkAnonymizationKey` from a `NetworkIsolationKey`. This is
   // possible because a `NetworkIsolationKey` must always be more granular
@@ -120,7 +120,7 @@
   static NetworkAnonymizationKey CreateFromParts(
       const SchemefulSite& top_frame_site,
       bool is_cross_site,
-      absl::optional<base::UnguessableToken> nonce = absl::nullopt) {
+      std::optional<base::UnguessableToken> nonce = std::nullopt) {
     return NetworkAnonymizationKey(top_frame_site, is_cross_site, nonce);
   }
 
@@ -145,7 +145,7 @@
   bool IsTransient() const;
 
   // Getters for the top frame, frame site, nonce and is cross site flag.
-  const absl::optional<SchemefulSite>& GetTopFrameSite() const {
+  const std::optional<SchemefulSite>& GetTopFrameSite() const {
     return top_frame_site_;
   }
 
@@ -153,7 +153,7 @@
 
   bool IsSameSite() const { return !IsCrossSite(); }
 
-  const absl::optional<base::UnguessableToken>& GetNonce() const {
+  const std::optional<base::UnguessableToken>& GetNonce() const {
     return nonce_;
   }
 
@@ -191,24 +191,24 @@
   NetworkAnonymizationKey(
       const SchemefulSite& top_frame_site,
       bool is_cross_site,
-      absl::optional<base::UnguessableToken> nonce = absl::nullopt);
+      std::optional<base::UnguessableToken> nonce = std::nullopt);
 
   std::string GetSiteDebugString(
-      const absl::optional<SchemefulSite>& site) const;
+      const std::optional<SchemefulSite>& site) const;
 
-  static absl::optional<std::string> SerializeSiteWithNonce(
+  static std::optional<std::string> SerializeSiteWithNonce(
       const SchemefulSite& site);
 
   // The origin/etld+1 of the top frame of the page making the request. This
   // will always be populated unless all other fields are also nullopt.
-  absl::optional<SchemefulSite> top_frame_site_;
+  std::optional<SchemefulSite> top_frame_site_;
 
   // True if the frame site is cross site when compared to the top frame site.
   // This is always false for a non-fully-populated NAK.
   bool is_cross_site_;
 
   // for non-opaque origins.
-  absl::optional<base::UnguessableToken> nonce_;
+  std::optional<base::UnguessableToken> nonce_;
 };
 
 }  // namespace net
diff --git a/net/base/network_anonymization_key_unittest.cc b/net/base/network_anonymization_key_unittest.cc
index eded456..edc24b7 100644
--- a/net/base/network_anonymization_key_unittest.cc
+++ b/net/base/network_anonymization_key_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "net/base/network_anonymization_key.h"
 
+#include <optional>
+
 #include "base/test/gtest_util.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/unguessable_token.h"
@@ -12,7 +14,6 @@
 #include "net/base/schemeful_site.h"
 #include "network_anonymization_key.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/url_util.h"
 
@@ -194,7 +195,7 @@
   NetworkAnonymizationKey populated_key =
       NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
                                                /*is_cross_site=*/false,
-                                               /*nonce=*/absl::nullopt);
+                                               /*nonce=*/std::nullopt);
 
   EXPECT_TRUE(empty_key.IsEmpty());
   EXPECT_FALSE(populated_key.IsEmpty());
@@ -216,11 +217,11 @@
   NetworkAnonymizationKey populated_key =
       NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
                                                /*is_cross_site=*/false,
-                                               /*nonce=*/absl::nullopt);
+                                               /*nonce=*/std::nullopt);
   NetworkAnonymizationKey data_top_frame_key =
       NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kDataSite,
                                                /*is_cross_site=*/false,
-                                               /*nonce=*/absl::nullopt);
+                                               /*nonce=*/std::nullopt);
   NetworkAnonymizationKey populated_key_with_nonce =
       NetworkAnonymizationKey::CreateFromParts(
           /*top_frame_site=*/kTestSiteA,
@@ -228,7 +229,7 @@
   NetworkAnonymizationKey data_frame_key =
       NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
                                                /*is_cross_site=*/false,
-                                               /*nonce=*/absl::nullopt);
+                                               /*nonce=*/std::nullopt);
 
   NetworkAnonymizationKey from_create_transient =
       NetworkAnonymizationKey::CreateTransient();
@@ -242,7 +243,7 @@
   NetworkAnonymizationKey populated_double_key =
       NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
                                                /*is_cross_site=*/false,
-                                               /*nonce=*/absl::nullopt);
+                                               /*nonce=*/std::nullopt);
   EXPECT_FALSE(data_frame_key.IsTransient());
   EXPECT_FALSE(populated_double_key.IsTransient());
 }
@@ -252,13 +253,13 @@
   NetworkAnonymizationKey populated_key =
       NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
                                                /*is_cross_site=*/false,
-                                               /*nonce=*/absl::nullopt);
+                                               /*nonce=*/std::nullopt);
   EXPECT_TRUE(populated_key.IsFullyPopulated());
   EXPECT_FALSE(empty_key.IsFullyPopulated());
   NetworkAnonymizationKey empty_frame_site_key =
       NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
                                                /*is_cross_site=*/false,
-                                               /*nonce=*/absl::nullopt);
+                                               /*nonce=*/std::nullopt);
   EXPECT_TRUE(empty_frame_site_key.IsFullyPopulated());
 }
 
@@ -311,7 +312,7 @@
   NetworkAnonymizationKey key_no_nonce =
       NetworkAnonymizationKey::CreateFromParts(/*top_frame_site=*/kTestSiteA,
                                                /*is_cross_site=*/false,
-                                               /*nonce=*/absl::nullopt);
+                                               /*nonce=*/std::nullopt);
   EXPECT_FALSE(key == key_no_nonce);
   EXPECT_TRUE(key != key_no_nonce);
   EXPECT_FALSE(key < key_no_nonce);
diff --git a/net/base/network_change_notifier.cc b/net/base/network_change_notifier.cc
index 953c4ff..b35c0a1 100644
--- a/net/base/network_change_notifier.cc
+++ b/net/base/network_change_notifier.cc
@@ -5,6 +5,7 @@
 #include "net/base/network_change_notifier.h"
 
 #include <limits>
+#include <optional>
 #include <string>
 #include <unordered_set>
 #include <utility>
@@ -28,7 +29,6 @@
 #include "net/dns/dns_config_service.h"
 #include "net/dns/system_dns_config_change_notifier.h"
 #include "net/url_request/url_request.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 #if BUILDFLAG(IS_WIN)
@@ -261,7 +261,7 @@
  public:
   virtual ~SystemDnsConfigObserver() = default;
 
-  void OnSystemDnsConfigChanged(absl::optional<DnsConfig> config) override {
+  void OnSystemDnsConfigChanged(std::optional<DnsConfig> config) override {
     NotifyObserversOfDNSChange();
   }
 };
diff --git a/net/base/network_change_notifier_fuchsia.cc b/net/base/network_change_notifier_fuchsia.cc
index 5a313935..d13b0a2a 100644
--- a/net/base/network_change_notifier_fuchsia.cc
+++ b/net/base/network_change_notifier_fuchsia.cc
@@ -8,6 +8,7 @@
 #include <lib/sys/cpp/component_context.h>
 
 #include <algorithm>
+#include <optional>
 #include <utility>
 #include <vector>
 
@@ -18,7 +19,6 @@
 #include "base/threading/thread_checker.h"
 #include "base/types/expected.h"
 #include "net/base/fuchsia/network_interface_cache.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -98,7 +98,7 @@
 }
 
 void NetworkChangeNotifierFuchsia::HandleCacheStatus(
-    absl::optional<internal::NetworkInterfaceCache::ChangeBits> change_bits) {
+    std::optional<internal::NetworkInterfaceCache::ChangeBits> change_bits) {
   if (!change_bits.has_value()) {
     watcher_.Unbind();
     return;
diff --git a/net/base/network_change_notifier_fuchsia.h b/net/base/network_change_notifier_fuchsia.h
index ba010db..9ad52d5 100644
--- a/net/base/network_change_notifier_fuchsia.h
+++ b/net/base/network_change_notifier_fuchsia.h
@@ -7,6 +7,7 @@
 
 #include <fuchsia/net/interfaces/cpp/fidl.h>
 
+#include <optional>
 #include <vector>
 
 #include "base/threading/thread_checker.h"
@@ -14,7 +15,6 @@
 #include "net/base/fuchsia/network_interface_cache.h"
 #include "net/base/net_export.h"
 #include "net/base/network_change_notifier.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -52,7 +52,7 @@
 
   // Notifies observers of changes. Unbinds `watcher_` if there was an error.
   void HandleCacheStatus(
-      absl::optional<internal::NetworkInterfaceCache::ChangeBits> change_bits);
+      std::optional<internal::NetworkInterfaceCache::ChangeBits> change_bits);
 
   fuchsia::net::interfaces::WatcherPtr watcher_;
 
diff --git a/net/base/network_delegate.cc b/net/base/network_delegate.cc
index c1509b7..6aad5c0 100644
--- a/net/base/network_delegate.cc
+++ b/net/base/network_delegate.cc
@@ -53,7 +53,7 @@
     const HttpResponseHeaders* original_response_headers,
     scoped_refptr<HttpResponseHeaders>* override_response_headers,
     const IPEndPoint& endpoint,
-    absl::optional<GURL>* preserve_fragment_on_redirect_url) {
+    std::optional<GURL>* preserve_fragment_on_redirect_url) {
   TRACE_EVENT0(NetTracingCategory(), "NetworkDelegate::NotifyHeadersReceived");
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(original_response_headers);
diff --git a/net/base/network_delegate.h b/net/base/network_delegate.h
index 5e4debf..d1bd6c2 100644
--- a/net/base/network_delegate.h
+++ b/net/base/network_delegate.h
@@ -7,6 +7,7 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <set>
 #include <string>
 
@@ -23,7 +24,6 @@
 #include "net/first_party_sets/first_party_set_metadata.h"
 #include "net/first_party_sets/first_party_sets_cache_filter.h"
 #include "net/proxy_resolution/proxy_retry_info.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class GURL;
 
@@ -62,7 +62,7 @@
                              CompletionOnceCallback callback,
                              GURL* new_url);
   using OnBeforeStartTransactionCallback =
-      base::OnceCallback<void(int, const absl::optional<HttpRequestHeaders>&)>;
+      base::OnceCallback<void(int, const std::optional<HttpRequestHeaders>&)>;
   int NotifyBeforeStartTransaction(URLRequest* request,
                                    const HttpRequestHeaders& headers,
                                    OnBeforeStartTransactionCallback callback);
@@ -72,7 +72,7 @@
       const HttpResponseHeaders* original_response_headers,
       scoped_refptr<HttpResponseHeaders>* override_response_headers,
       const IPEndPoint& remote_endpoint,
-      absl::optional<GURL>* preserve_fragment_on_redirect_url);
+      std::optional<GURL>* preserve_fragment_on_redirect_url);
   void NotifyBeforeRedirect(URLRequest* request,
                             const GURL& new_location);
   void NotifyResponseStarted(URLRequest* request, int net_error);
@@ -213,7 +213,7 @@
       const HttpResponseHeaders* original_response_headers,
       scoped_refptr<HttpResponseHeaders>* override_response_headers,
       const IPEndPoint& remote_endpoint,
-      absl::optional<GURL>* preserve_fragment_on_redirect_url) = 0;
+      std::optional<GURL>* preserve_fragment_on_redirect_url) = 0;
 
   // Called right after a redirect response code was received. |new_location| is
   // only valid for the duration of the call.
diff --git a/net/base/network_delegate_impl.cc b/net/base/network_delegate_impl.cc
index 13333c9..d4c02a7 100644
--- a/net/base/network_delegate_impl.cc
+++ b/net/base/network_delegate_impl.cc
@@ -28,7 +28,7 @@
     const HttpResponseHeaders* original_response_headers,
     scoped_refptr<HttpResponseHeaders>* override_response_headers,
     const IPEndPoint& endpoint,
-    absl::optional<GURL>* preserve_fragment_on_redirect_url) {
+    std::optional<GURL>* preserve_fragment_on_redirect_url) {
   return OK;
 }
 
diff --git a/net/base/network_delegate_impl.h b/net/base/network_delegate_impl.h
index 5a5891a..812f471 100644
--- a/net/base/network_delegate_impl.h
+++ b/net/base/network_delegate_impl.h
@@ -7,6 +7,7 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <set>
 #include <string>
 
@@ -18,7 +19,6 @@
 #include "net/first_party_sets/first_party_set_metadata.h"
 #include "net/first_party_sets/first_party_sets_cache_filter.h"
 #include "net/proxy_resolution/proxy_retry_info.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class GURL;
 
@@ -57,7 +57,7 @@
       const HttpResponseHeaders* original_response_headers,
       scoped_refptr<HttpResponseHeaders>* override_response_headers,
       const IPEndPoint& endpoint,
-      absl::optional<GURL>* preserve_fragment_on_redirect_url) override;
+      std::optional<GURL>* preserve_fragment_on_redirect_url) override;
 
   void OnBeforeRedirect(URLRequest* request, const GURL& new_location) override;
 
diff --git a/net/base/network_interfaces.cc b/net/base/network_interfaces.cc
index a89c65d..c8a66341 100644
--- a/net/base/network_interfaces.cc
+++ b/net/base/network_interfaces.cc
@@ -29,7 +29,7 @@
                                    const IPAddress& address,
                                    uint32_t prefix_length,
                                    int ip_address_attributes,
-                                   absl::optional<Eui48MacAddress> mac_address)
+                                   std::optional<Eui48MacAddress> mac_address)
     : name(name),
       friendly_name(friendly_name),
       interface_index(interface_index),
diff --git a/net/base/network_interfaces.h b/net/base/network_interfaces.h
index 75e25c3..ffe63c2 100644
--- a/net/base/network_interfaces.h
+++ b/net/base/network_interfaces.h
@@ -9,6 +9,7 @@
 
 #include <array>
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -16,8 +17,6 @@
 #include "net/base/net_export.h"
 #include "net/base/network_change_notifier.h"
 
-#include "third_party/abseil-cpp/absl/types/optional.h"
-
 namespace net {
 
 // A subset of IP address attributes which are actionable by the
@@ -63,7 +62,7 @@
                    const IPAddress& address,
                    uint32_t prefix_length,
                    int ip_address_attributes,
-                   absl::optional<Eui48MacAddress> mac_address = absl::nullopt);
+                   std::optional<Eui48MacAddress> mac_address = std::nullopt);
   NetworkInterface(const NetworkInterface& other);
   ~NetworkInterface();
 
@@ -74,7 +73,7 @@
   IPAddress address;
   uint32_t prefix_length;
   int ip_address_attributes;  // Combination of |IPAddressAttributes|.
-  absl::optional<Eui48MacAddress> mac_address;
+  std::optional<Eui48MacAddress> mac_address;
 };
 
 typedef std::vector<NetworkInterface> NetworkInterfaceList;
diff --git a/net/base/network_interfaces_fuchsia.cc b/net/base/network_interfaces_fuchsia.cc
index facc96bf..c70a9cd2 100644
--- a/net/base/network_interfaces_fuchsia.cc
+++ b/net/base/network_interfaces_fuchsia.cc
@@ -7,6 +7,7 @@
 #include <fuchsia/net/interfaces/cpp/fidl.h>
 #include <zircon/types.h>
 
+#include <optional>
 #include <string>
 #include <utility>
 
@@ -15,7 +16,6 @@
 #include "net/base/network_change_notifier.h"
 #include "net/base/network_change_notifier_fuchsia.h"
 #include "net/base/network_interfaces.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 namespace internal {
@@ -35,11 +35,11 @@
 }  // namespace
 
 // static
-absl::optional<InterfaceProperties> InterfaceProperties::VerifyAndCreate(
+std::optional<InterfaceProperties> InterfaceProperties::VerifyAndCreate(
     fuchsia::net::interfaces::Properties properties) {
   if (!internal::VerifyCompleteInterfaceProperties(properties))
-    return absl::nullopt;
-  return absl::make_optional(InterfaceProperties(std::move(properties)));
+    return std::nullopt;
+  return std::make_optional(InterfaceProperties(std::move(properties)));
 }
 
 InterfaceProperties::InterfaceProperties(
diff --git a/net/base/network_interfaces_fuchsia.h b/net/base/network_interfaces_fuchsia.h
index c758687..100a717 100644
--- a/net/base/network_interfaces_fuchsia.h
+++ b/net/base/network_interfaces_fuchsia.h
@@ -8,9 +8,10 @@
 #include <fuchsia/net/interfaces/cpp/fidl.h>
 #include <stdint.h>
 
+#include <optional>
+
 #include "net/base/network_change_notifier.h"
 #include "net/base/network_interfaces.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net::internal {
 
@@ -23,7 +24,7 @@
 
   // Creates an |InterfaceProperties| if |properties| are valid complete
   // properties as reported by |VerifyCompleteInterfaceProperties|.
-  static absl::optional<InterfaceProperties> VerifyAndCreate(
+  static std::optional<InterfaceProperties> VerifyAndCreate(
       fuchsia::net::interfaces::Properties properties);
   InterfaceProperties(InterfaceProperties&& interface);
   InterfaceProperties& operator=(InterfaceProperties&& interface);
diff --git a/net/base/network_interfaces_linux.cc b/net/base/network_interfaces_linux.cc
index 9ab50b7..c192c33 100644
--- a/net/base/network_interfaces_linux.cc
+++ b/net/base/network_interfaces_linux.cc
@@ -5,6 +5,7 @@
 #include "net/base/network_interfaces_linux.h"
 
 #include <memory>
+#include <optional>
 
 #include "build/build_config.h"
 
@@ -33,12 +34,12 @@
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_errors.h"
 #include "net/base/network_interfaces_posix.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
 #if BUILDFLAG(IS_ANDROID)
+#include <string_view>
+
 #include "base/android/build_info.h"
-#include "base/strings/string_piece.h"
 #include "net/android/network_library.h"
 #include "net/base/network_interfaces_getifaddrs.h"
 #endif
@@ -233,7 +234,7 @@
     // so use a Chromium's own implementation to workaround.
     // See https://crbug.com/1240237 for more context.
     bool use_alternative_getifaddrs =
-        base::StringPiece(build_info->brand()) == "samsung" &&
+        std::string_view(build_info->brand()) == "samsung" &&
         base::StartsWith(build_info->hardware(), "mt");
     bool ret = internal::GetNetworkListUsingGetifaddrs(
         networks, policy, use_alternative_getifaddrs);
@@ -245,7 +246,7 @@
 #endif  // BUILDFLAG(IS_ANDROID)
 
   const AddressMapOwnerLinux* map_owner = nullptr;
-  absl::optional<internal::AddressTrackerLinux> temp_tracker;
+  std::optional<internal::AddressTrackerLinux> temp_tracker;
 #if BUILDFLAG(IS_LINUX)
   // If NetworkChangeNotifier already maintains a map owner in this process, use
   // it.
diff --git a/net/base/network_interfaces_win.cc b/net/base/network_interfaces_win.cc
index 6f6f32a..c6e1f3c 100644
--- a/net/base/network_interfaces_win.cc
+++ b/net/base/network_interfaces_win.cc
@@ -6,11 +6,11 @@
 
 #include <algorithm>
 #include <memory>
+#include <string_view>
 
 #include "base/files/file_path.h"
 #include "base/lazy_instance.h"
 #include "base/strings/escape.h"
-#include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -152,7 +152,7 @@
       continue;
     }
 
-    absl::optional<Eui48MacAddress> mac_address;
+    std::optional<Eui48MacAddress> mac_address;
     mac_address.emplace();
     if (adapter->PhysicalAddressLength == mac_address->size()) {
       std::copy_n(reinterpret_cast<const uint8_t*>(adapter->PhysicalAddress),
diff --git a/net/base/network_isolation_key.cc b/net/base/network_isolation_key.cc
index 39d6dd51..91c5abbc 100644
--- a/net/base/network_isolation_key.cc
+++ b/net/base/network_isolation_key.cc
@@ -2,15 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "net/base/network_isolation_key.h"
+
 #include <cstddef>
+#include <optional>
 #include <string>
 
 #include "base/unguessable_token.h"
 #include "net/base/features.h"
-#include "net/base/network_isolation_key.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 #include "schemeful_site.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 #include "url/url_constants.h"
@@ -19,7 +20,7 @@
 
 namespace {
 
-std::string GetSiteDebugString(const absl::optional<SchemefulSite>& site) {
+std::string GetSiteDebugString(const std::optional<SchemefulSite>& site) {
   return site ? site->GetDebugString() : "null";
 }
 
@@ -28,20 +29,20 @@
 NetworkIsolationKey::NetworkIsolationKey(
     const SchemefulSite& top_frame_site,
     const SchemefulSite& frame_site,
-    const absl::optional<base::UnguessableToken>& nonce)
+    const std::optional<base::UnguessableToken>& nonce)
     : NetworkIsolationKey(SchemefulSite(top_frame_site),
                           SchemefulSite(frame_site),
-                          absl::optional<base::UnguessableToken>(nonce)) {}
+                          std::optional<base::UnguessableToken>(nonce)) {}
 
 NetworkIsolationKey::NetworkIsolationKey(
     SchemefulSite&& top_frame_site,
     SchemefulSite&& frame_site,
-    absl::optional<base::UnguessableToken>&& nonce)
+    std::optional<base::UnguessableToken>&& nonce)
     : top_frame_site_(std::move(top_frame_site)),
-      frame_site_(absl::make_optional(std::move(frame_site))),
+      frame_site_(std::make_optional(std::move(frame_site))),
       is_cross_site_((GetMode() == Mode::kCrossSiteFlagEnabled)
-                         ? absl::make_optional(*top_frame_site_ != *frame_site_)
-                         : absl::nullopt),
+                         ? std::make_optional(*top_frame_site_ != *frame_site_)
+                         : std::nullopt),
       nonce_(std::move(nonce)) {
   DCHECK(!nonce_ || !nonce_->is_empty());
 }
@@ -81,9 +82,9 @@
   return key;
 }
 
-absl::optional<std::string> NetworkIsolationKey::ToCacheKeyString() const {
+std::optional<std::string> NetworkIsolationKey::ToCacheKeyString() const {
   if (IsTransient())
-    return absl::nullopt;
+    return std::nullopt;
 
   std::string variable_key_piece;
   switch (GetMode()) {
diff --git a/net/base/network_isolation_key.h b/net/base/network_isolation_key.h
index 7784c50e..9c159400 100644
--- a/net/base/network_isolation_key.h
+++ b/net/base/network_isolation_key.h
@@ -5,13 +5,13 @@
 #ifndef NET_BASE_NETWORK_ISOLATION_KEY_H_
 #define NET_BASE_NETWORK_ISOLATION_KEY_H_
 
+#include <optional>
 #include <string>
 
 #include "base/types/pass_key.h"
 #include "base/unguessable_token.h"
 #include "net/base/net_export.h"
 #include "net/base/schemeful_site.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace url {
 class Origin;
@@ -37,13 +37,13 @@
   NetworkIsolationKey(
       const SchemefulSite& top_frame_site,
       const SchemefulSite& frame_site,
-      const absl::optional<base::UnguessableToken>& nonce = absl::nullopt);
+      const std::optional<base::UnguessableToken>& nonce = std::nullopt);
 
   // Alternative constructor that takes ownership of arguments, to save copies.
   NetworkIsolationKey(
       SchemefulSite&& top_frame_site,
       SchemefulSite&& frame_site,
-      absl::optional<base::UnguessableToken>&& nonce = absl::nullopt);
+      std::optional<base::UnguessableToken>&& nonce = std::nullopt);
 
   // Legacy constructor.
   // TODO(https://crbug.com/1145294):  Remove this in favor of above
@@ -122,7 +122,7 @@
   // cache. This is the string representation of each piece of the key separated
   // by spaces. Returns nullopt if the network isolation key is transient, in
   // which case, nothing should typically be saved to disk using the key.
-  absl::optional<std::string> ToCacheKeyString() const;
+  std::optional<std::string> ToCacheKeyString() const;
 
   // Returns string for debugging. Difference from ToString() is that transient
   // entries may be distinguishable from each other.
@@ -139,7 +139,7 @@
   // Getters for the top frame and frame sites. These accessors are primarily
   // intended for IPC calls, and to be able to create an IsolationInfo from a
   // NetworkIsolationKey.
-  const absl::optional<SchemefulSite>& GetTopFrameSite() const {
+  const std::optional<SchemefulSite>& GetTopFrameSite() const {
     return top_frame_site_;
   }
 
@@ -148,7 +148,7 @@
     // partition the HTTP cache. This key will have the following properties:
     // `top_frame_site` -> the schemeful site of the top level page.
     // `frame_site ` -> the schemeful site of the frame.
-    // `is_cross_site` -> absl::nullopt.
+    // `is_cross_site` -> std::nullopt.
     kFrameSiteEnabled,
     // This scheme indicates that "2.5-key" NetworkIsolationKeys are used to
     // partition the HTTP cache. This key will have the following properties:
@@ -170,20 +170,20 @@
   static Mode GetMode();
 
   // Do not use outside of testing. Returns the `frame_site_`.
-  const absl::optional<SchemefulSite> GetFrameSiteForTesting() const {
+  const std::optional<SchemefulSite> GetFrameSiteForTesting() const {
     if (GetMode() == Mode::kFrameSiteEnabled ||
         GetMode() == Mode::kFrameSiteWithSharedOpaqueEnabled) {
       return frame_site_;
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // Do not use outside of testing. Returns `is_cross_site_`.
-  const absl::optional<bool> GetIsCrossSiteForTesting() const {
+  const std::optional<bool> GetIsCrossSiteForTesting() const {
     if (GetMode() == Mode::kCrossSiteFlagEnabled) {
       return is_cross_site_;
     }
-    return absl::nullopt;
+    return std::nullopt;
   }
 
   // When serializing a NIK for sending via mojo we want to access the frame
@@ -192,7 +192,7 @@
   using SerializationPassKey = base::PassKey<struct mojo::StructTraits<
       network::mojom::NonEmptyNetworkIsolationKeyDataView,
       NetworkIsolationKey>>;
-  const absl::optional<SchemefulSite>& GetFrameSiteForSerialization(
+  const std::optional<SchemefulSite>& GetFrameSiteForSerialization(
       SerializationPassKey) const {
     CHECK(!IsEmpty());
     return frame_site_;
@@ -201,7 +201,7 @@
   // CookiePartitionKey for nonced partitions. We also use a passkey for this
   // case.
   using CookiePartitionKeyPassKey = base::PassKey<CookiePartitionKey>;
-  const absl::optional<SchemefulSite>& GetFrameSiteForCookiePartitionKey(
+  const std::optional<SchemefulSite>& GetFrameSiteForCookiePartitionKey(
       CookiePartitionKeyPassKey) const {
     CHECK(!IsEmpty());
     return frame_site_;
@@ -209,14 +209,14 @@
   // Same as above but for constructing a `NetworkAnonymizationKey()` from this
   // NIK.
   using NetworkAnonymizationKeyPassKey = base::PassKey<NetworkAnonymizationKey>;
-  const absl::optional<SchemefulSite>& GetFrameSiteForNetworkAnonymizationKey(
+  const std::optional<SchemefulSite>& GetFrameSiteForNetworkAnonymizationKey(
       NetworkAnonymizationKeyPassKey) const {
     CHECK(!IsEmpty());
     return frame_site_;
   }
 
   // Getter for the nonce.
-  const absl::optional<base::UnguessableToken>& GetNonce() const {
+  const std::optional<base::UnguessableToken>& GetNonce() const {
     return nonce_;
   }
 
@@ -228,10 +228,10 @@
   bool IsOpaque() const;
 
   // The origin/etld+1 of the top frame of the page making the request.
-  absl::optional<SchemefulSite> top_frame_site_;
+  std::optional<SchemefulSite> top_frame_site_;
 
   // The origin/etld+1 of the frame that initiates the request.
-  absl::optional<SchemefulSite> frame_site_;
+  std::optional<SchemefulSite> frame_site_;
 
   // A boolean indicating whether the frame origin is cross-site from the
   // top-level origin. This will be used for experiments to determine the
@@ -239,14 +239,14 @@
   // top-level origin and frame origin ("triple-keying") vs. the top-level
   // origin and an is-cross-site bit ("2.5-keying") like the
   // `NetworkAnonymizationKey` uses for network state partitioning. This will be
-  // absl::nullopt when `GetMode()` returns `Mode::kFrameSiteEnabled` or
+  // std::nullopt when `GetMode()` returns `Mode::kFrameSiteEnabled` or
   // `Mode::kFrameSiteWithSharedOpaqueEnabled`, or for an empty
   // `NetworkIsolationKey`.
-  absl::optional<bool> is_cross_site_;
+  std::optional<bool> is_cross_site_;
 
   // Having a nonce is a way to force a transient opaque `NetworkIsolationKey`
   // for non-opaque origins.
-  absl::optional<base::UnguessableToken> nonce_;
+  std::optional<base::UnguessableToken> nonce_;
 };
 
 }  // namespace net
diff --git a/net/base/network_isolation_key_unittest.cc b/net/base/network_isolation_key_unittest.cc
index a73aa71..dcba862 100644
--- a/net/base/network_isolation_key_unittest.cc
+++ b/net/base/network_isolation_key_unittest.cc
@@ -4,13 +4,14 @@
 
 #include "net/base/network_isolation_key.h"
 
+#include <optional>
+
 #include "base/test/scoped_feature_list.h"
 #include "base/unguessable_token.h"
 #include "base/values.h"
 #include "net/base/features.h"
 #include "net/base/schemeful_site.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/url_util.h"
 
@@ -72,7 +73,7 @@
 TEST_P(NetworkIsolationKeyTest, EmptyKey) {
   NetworkIsolationKey key;
   EXPECT_FALSE(key.IsFullyPopulated());
-  EXPECT_EQ(absl::nullopt, key.ToCacheKeyString());
+  EXPECT_EQ(std::nullopt, key.ToCacheKeyString());
   EXPECT_TRUE(key.IsTransient());
   switch (NetworkIsolationKey::GetMode()) {
     case NetworkIsolationKey::Mode::kFrameSiteEnabled:
@@ -134,7 +135,7 @@
   base::UnguessableToken nonce = base::UnguessableToken::Create();
   NetworkIsolationKey key(site1, site2, nonce);
   EXPECT_TRUE(key.IsFullyPopulated());
-  EXPECT_EQ(absl::nullopt, key.ToCacheKeyString());
+  EXPECT_EQ(std::nullopt, key.ToCacheKeyString());
   EXPECT_TRUE(key.IsTransient());
   switch (NetworkIsolationKey::GetMode()) {
     case NetworkIsolationKey::Mode::kFrameSiteEnabled:
@@ -167,7 +168,7 @@
   SchemefulSite site_data = SchemefulSite(GURL(kDataUrl));
   NetworkIsolationKey key(site_data, site_data);
   EXPECT_TRUE(key.IsFullyPopulated());
-  EXPECT_EQ(absl::nullopt, key.ToCacheKeyString());
+  EXPECT_EQ(std::nullopt, key.ToCacheKeyString());
   EXPECT_TRUE(key.IsTransient());
   switch (NetworkIsolationKey::GetMode()) {
     case NetworkIsolationKey::Mode::kFrameSiteEnabled:
@@ -212,7 +213,7 @@
   SchemefulSite site_data = SchemefulSite(GURL(kDataUrl));
   NetworkIsolationKey key(site_data, site1);
   EXPECT_TRUE(key.IsFullyPopulated());
-  EXPECT_EQ(absl::nullopt, key.ToCacheKeyString());
+  EXPECT_EQ(std::nullopt, key.ToCacheKeyString());
   EXPECT_TRUE(key.IsTransient());
   switch (NetworkIsolationKey::GetMode()) {
     case NetworkIsolationKey::Mode::kFrameSiteEnabled:
@@ -252,7 +253,7 @@
   EXPECT_TRUE(key.IsFullyPopulated());
   switch (NetworkIsolationKey::GetMode()) {
     case NetworkIsolationKey::Mode::kFrameSiteEnabled:
-      EXPECT_EQ(absl::nullopt, key.ToCacheKeyString());
+      EXPECT_EQ(std::nullopt, key.ToCacheKeyString());
       EXPECT_TRUE(key.IsTransient());
       EXPECT_EQ(site1.GetDebugString() + " " + site_data.GetDebugString(),
                 key.ToDebugString());
@@ -400,9 +401,9 @@
 
   // Test the ToString and ToDebugString
   EXPECT_EQ(key1.ToDebugString(), key2.ToDebugString());
-  EXPECT_EQ(absl::nullopt, key1.ToCacheKeyString());
-  EXPECT_EQ(absl::nullopt, key2.ToCacheKeyString());
-  EXPECT_EQ(absl::nullopt, key3.ToCacheKeyString());
+  EXPECT_EQ(std::nullopt, key1.ToCacheKeyString());
+  EXPECT_EQ(std::nullopt, key2.ToCacheKeyString());
+  EXPECT_EQ(std::nullopt, key3.ToCacheKeyString());
 }
 
 // Make sure that the logic to extract the registerable domain from an origin
diff --git a/net/base/parse_number.cc b/net/base/parse_number.cc
index f6506bb..ad6e3198 100644
--- a/net/base/parse_number.cc
+++ b/net/base/parse_number.cc
@@ -16,21 +16,21 @@
 // consistent interface to StringToXXX() that calls the appropriate //base
 // version. This simplifies writing generic code with a template.
 
-bool StringToNumber(base::StringPiece input, int32_t* output) {
+bool StringToNumber(std::string_view input, int32_t* output) {
   // This assumes ints are 32-bits (will fail compile if that ever changes).
   return base::StringToInt(input, output);
 }
 
-bool StringToNumber(base::StringPiece input, uint32_t* output) {
+bool StringToNumber(std::string_view input, uint32_t* output) {
   // This assumes ints are 32-bits (will fail compile if that ever changes).
   return base::StringToUint(input, output);
 }
 
-bool StringToNumber(base::StringPiece input, int64_t* output) {
+bool StringToNumber(std::string_view input, int64_t* output) {
   return base::StringToInt64(input, output);
 }
 
-bool StringToNumber(base::StringPiece input, uint64_t* output) {
+bool StringToNumber(std::string_view input, uint64_t* output) {
   return base::StringToUint64(input, output);
 }
 
@@ -41,7 +41,7 @@
 }
 
 template <typename T>
-bool ParseIntHelper(base::StringPiece input,
+bool ParseIntHelper(std::string_view input,
                     ParseIntFormat format,
                     T* output,
                     ParseIntError* optional_error) {
@@ -97,7 +97,7 @@
   // as it has ambiguity with parse errors.
 
   // Strip any leading negative sign off the number.
-  base::StringPiece numeric_portion =
+  std::string_view numeric_portion =
       starts_with_negative ? input.substr(1) : input;
 
   // Test if |numeric_portion| is a valid non-negative integer.
@@ -115,21 +115,21 @@
 
 }  // namespace
 
-bool ParseInt32(base::StringPiece input,
+bool ParseInt32(std::string_view input,
                 ParseIntFormat format,
                 int32_t* output,
                 ParseIntError* optional_error) {
   return ParseIntHelper(input, format, output, optional_error);
 }
 
-bool ParseInt64(base::StringPiece input,
+bool ParseInt64(std::string_view input,
                 ParseIntFormat format,
                 int64_t* output,
                 ParseIntError* optional_error) {
   return ParseIntHelper(input, format, output, optional_error);
 }
 
-bool ParseUint32(base::StringPiece input,
+bool ParseUint32(std::string_view input,
                  ParseIntFormat format,
                  uint32_t* output,
                  ParseIntError* optional_error) {
@@ -138,7 +138,7 @@
   return ParseIntHelper(input, format, output, optional_error);
 }
 
-bool ParseUint64(base::StringPiece input,
+bool ParseUint64(std::string_view input,
                  ParseIntFormat format,
                  uint64_t* output,
                  ParseIntError* optional_error) {
diff --git a/net/base/parse_number.h b/net/base/parse_number.h
index f923b18..f70619a 100644
--- a/net/base/parse_number.h
+++ b/net/base/parse_number.h
@@ -6,8 +6,8 @@
 #define NET_BASE_PARSE_NUMBER_H_
 
 #include <cstdint>
+#include <string_view>
 
-#include "base/strings/string_piece.h"
 #include "net/base/net_export.h"
 
 // This file contains utility functions for parsing numbers, in the context of
@@ -92,13 +92,13 @@
 // |optional_error| was non-null, then it is filled with the reason for the
 // failure.
 [[nodiscard]] NET_EXPORT bool ParseInt32(
-    base::StringPiece input,
+    std::string_view input,
     ParseIntFormat format,
     int32_t* output,
     ParseIntError* optional_error = nullptr);
 
 [[nodiscard]] NET_EXPORT bool ParseInt64(
-    base::StringPiece input,
+    std::string_view input,
     ParseIntFormat format,
     int64_t* output,
     ParseIntError* optional_error = nullptr);
@@ -108,13 +108,13 @@
 // These are equivalent to calling ParseInt*(), except with unsigned output
 // types. ParseIntFormat may only be one of {NON_NEGATIVE, STRICT_NON_NEGATIVE}.
 [[nodiscard]] NET_EXPORT bool ParseUint32(
-    base::StringPiece input,
+    std::string_view input,
     ParseIntFormat format,
     uint32_t* output,
     ParseIntError* optional_error = nullptr);
 
 [[nodiscard]] NET_EXPORT bool ParseUint64(
-    base::StringPiece input,
+    std::string_view input,
     ParseIntFormat format,
     uint64_t* output,
     ParseIntError* optional_error = nullptr);
diff --git a/net/base/parse_number_unittest.cc b/net/base/parse_number_unittest.cc
index a0fceb5..548b338 100644
--- a/net/base/parse_number_unittest.cc
+++ b/net/base/parse_number_unittest.cc
@@ -72,7 +72,7 @@
 // This wrapper calls func() and expects the result to match |expected_output|.
 template <typename OutputType, typename ParseFunc, typename ExpectationType>
 void ExpectParseIntSuccess(ParseFunc func,
-                           base::StringPiece input,
+                           std::string_view input,
                            ParseIntFormat format,
                            ExpectationType expected_output) {
   // Try parsing without specifying an error output - expecting success.
@@ -95,7 +95,7 @@
 // This wrapper calls func() and expects the failure to match |expected_error|.
 template <typename OutputType, typename ParseFunc>
 void ExpectParseIntFailure(ParseFunc func,
-                           base::StringPiece input,
+                           std::string_view input,
                            ParseIntFormat format,
                            ParseIntError expected_error) {
   const OutputType kBogusOutput(23614);
@@ -192,7 +192,7 @@
 
   // Test parsing a string that contains a valid number followed by a NUL
   // character.
-  ExpectParseIntFailure<T>(func, base::StringPiece("123\0", 4), format,
+  ExpectParseIntFailure<T>(func, std::string_view("123\0", 4), format,
                            ParseIntError::FAILED_PARSE);
 }
 
diff --git a/net/base/parse_url_hostname_to_address_fuzzer.cc b/net/base/parse_url_hostname_to_address_fuzzer.cc
index a96ab05..6aa6bfea 100644
--- a/net/base/parse_url_hostname_to_address_fuzzer.cc
+++ b/net/base/parse_url_hostname_to_address_fuzzer.cc
@@ -6,14 +6,14 @@
 #include <stdint.h>
 
 #include <functional>
+#include <string_view>
 
-#include "base/strings/string_piece.h"
 #include "net/base/address_list.h"
 #include "net/base/ip_address.h"
 
 // Entry point for LibFuzzer.
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-  const base::StringPiece hostname(reinterpret_cast<const char*>(data), size);
+  const std::string_view hostname(reinterpret_cast<const char*>(data), size);
   net::IPAddress address;
 
   if (net::ParseURLHostnameToAddress(hostname, &address)) {
diff --git a/net/base/port_util.cc b/net/base/port_util.cc
index a2344f6..1d75d7ba 100644
--- a/net/base/port_util.cc
+++ b/net/base/port_util.cc
@@ -130,7 +130,7 @@
   return port >= 0 && port < 1024;
 }
 
-bool IsPortAllowedForScheme(int port, base::StringPiece url_scheme) {
+bool IsPortAllowedForScheme(int port, std::string_view url_scheme) {
   // Reject invalid ports.
   if (!IsPortValid(port))
     return false;
diff --git a/net/base/port_util.h b/net/base/port_util.h
index e271809..91f707c 100644
--- a/net/base/port_util.h
+++ b/net/base/port_util.h
@@ -8,8 +8,9 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <string_view>
+
 #include "base/containers/span.h"
-#include "base/strings/string_piece.h"
 #include "net/base/net_export.h"
 
 namespace net {
@@ -25,7 +26,7 @@
 // Checks if the port is allowed for the specified scheme.  Ports set as allowed
 // with SetExplicitlyAllowedPorts() or by using ScopedPortException() will be
 // considered allowed for any scheme.
-NET_EXPORT bool IsPortAllowedForScheme(int port, base::StringPiece url_scheme);
+NET_EXPORT bool IsPortAllowedForScheme(int port, std::string_view url_scheme);
 
 // Returns the number of explicitly allowed ports; for testing.
 NET_EXPORT_PRIVATE size_t GetCountOfExplicitlyAllowedPorts();
diff --git a/net/base/proxy_chain.cc b/net/base/proxy_chain.cc
index b4432b0..0722fb1 100644
--- a/net/base/proxy_chain.cc
+++ b/net/base/proxy_chain.cc
@@ -14,7 +14,7 @@
 namespace net {
 
 ProxyChain::ProxyChain() {
-  proxy_server_list_ = absl::nullopt;
+  proxy_server_list_ = std::nullopt;
 }
 
 ProxyChain::ProxyChain(const ProxyChain& other) = default;
@@ -39,7 +39,7 @@
 ProxyChain::ProxyChain(std::vector<ProxyServer> proxy_server_list)
     : proxy_server_list_(std::move(proxy_server_list)) {
   if (!IsValidInternal()) {
-    proxy_server_list_ = absl::nullopt;
+    proxy_server_list_ = std::nullopt;
   }
 }
 
diff --git a/net/base/proxy_chain.h b/net/base/proxy_chain.h
index 173df3e8..f2d6d494 100644
--- a/net/base/proxy_chain.h
+++ b/net/base/proxy_chain.h
@@ -7,16 +7,16 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <ostream>
 #include <string>
+#include <string_view>
 #include <tuple>
 #include <vector>
 
-#include "base/strings/string_piece.h"
 #include "net/base/host_port_pair.h"
 #include "net/base/net_export.h"
 #include "net/base/proxy_server.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -57,14 +57,14 @@
   // `ProxyChain()` or `Direct()` respectively to create an invalid or direct
   // ProxyChain.
   static ProxyChain FromSchemeHostAndPort(ProxyServer::Scheme scheme,
-                                          base::StringPiece host,
-                                          base::StringPiece port_str) {
+                                          std::string_view host,
+                                          std::string_view port_str) {
     return ProxyChain(
         ProxyServer::FromSchemeHostAndPort(scheme, host, port_str));
   }
   static ProxyChain FromSchemeHostAndPort(ProxyServer::Scheme scheme,
-                                          base::StringPiece host,
-                                          absl::optional<uint16_t> port) {
+                                          std::string_view host,
+                                          std::optional<uint16_t> port) {
     return ProxyChain(ProxyServer::FromSchemeHostAndPort(scheme, host, port));
   }
   // Create a "direct" proxy chain, which includes no proxy servers.
@@ -79,7 +79,7 @@
   const std::vector<ProxyServer>& proxy_servers() const;
 
   // Get the ProxyServers in this chain, or `nullopt` if the chain is not valid.
-  const absl::optional<std::vector<ProxyServer>>& proxy_servers_if_valid()
+  const std::optional<std::vector<ProxyServer>>& proxy_servers_if_valid()
       const {
     return proxy_server_list_;
   }
@@ -132,7 +132,7 @@
   std::string ToDebugString() const;
 
  private:
-  absl::optional<std::vector<ProxyServer>> proxy_server_list_;
+  std::optional<std::vector<ProxyServer>> proxy_server_list_;
 
   // Returns true if this chain is valid.
   bool IsValidInternal() const;
diff --git a/net/base/proxy_chain_unittest.cc b/net/base/proxy_chain_unittest.cc
index 1324af5b1..81238d0 100644
--- a/net/base/proxy_chain_unittest.cc
+++ b/net/base/proxy_chain_unittest.cc
@@ -4,12 +4,12 @@
 
 #include "net/base/proxy_chain.h"
 
+#include <optional>
 #include <sstream>
 
 #include "base/strings/string_number_conversions.h"
 #include "net/base/proxy_string_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -83,7 +83,7 @@
   const struct {
     const ProxyServer::Scheme input_scheme;
     const char* const input_host;
-    const absl::optional<uint16_t> input_port;
+    const std::optional<uint16_t> input_port;
     const char* const input_port_str;
     const char* const expected_host;
     const uint16_t expected_port;
@@ -124,11 +124,11 @@
       {ProxyServer::SCHEME_SOCKS5, "foopy", 111, "111", "foopy", 111},
 
       // Default ports
-      {ProxyServer::SCHEME_HTTP, "foopy", absl::nullopt, "", "foopy", 80},
-      {ProxyServer::SCHEME_HTTPS, "foopy", absl::nullopt, "", "foopy", 443},
-      {ProxyServer::SCHEME_QUIC, "foopy", absl::nullopt, "", "foopy", 443},
-      {ProxyServer::SCHEME_SOCKS4, "foopy", absl::nullopt, "", "foopy", 1080},
-      {ProxyServer::SCHEME_SOCKS5, "foopy", absl::nullopt, "", "foopy", 1080},
+      {ProxyServer::SCHEME_HTTP, "foopy", std::nullopt, "", "foopy", 80},
+      {ProxyServer::SCHEME_HTTPS, "foopy", std::nullopt, "", "foopy", 443},
+      {ProxyServer::SCHEME_QUIC, "foopy", std::nullopt, "", "foopy", 443},
+      {ProxyServer::SCHEME_SOCKS4, "foopy", std::nullopt, "", "foopy", 1080},
+      {ProxyServer::SCHEME_SOCKS5, "foopy", std::nullopt, "", "foopy", 1080},
   };
 
   for (size_t i = 0; i < std::size(tests); ++i) {
diff --git a/net/base/proxy_server.cc b/net/base/proxy_server.cc
index 16756fa..8aa08ded 100644
--- a/net/base/proxy_server.cc
+++ b/net/base/proxy_server.cc
@@ -6,16 +6,16 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <ostream>
 #include <string>
+#include <string_view>
 
 #include "base/check_op.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/strcat.h"
 #include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece.h"
 #include "net/base/proxy_string_util.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/third_party/mozilla/url_parse.h"
 #include "url/url_canon.h"
 #include "url/url_canon_stdstring.h"
@@ -35,8 +35,8 @@
 
 // static
 ProxyServer ProxyServer::FromSchemeHostAndPort(Scheme scheme,
-                                               base::StringPiece host,
-                                               base::StringPiece port_str) {
+                                               std::string_view host,
+                                               std::string_view port_str) {
   // Create INVALID proxies directly using `ProxyServer()`.
   DCHECK_NE(scheme, SCHEME_INVALID);
 
@@ -46,7 +46,7 @@
   int port_number =
       url::ParsePort(port_str.data(), url::Component(0, port_str.size()));
   if (port_number == url::PORT_UNSPECIFIED)
-    return FromSchemeHostAndPort(scheme, host, absl::nullopt);
+    return FromSchemeHostAndPort(scheme, host, std::nullopt);
   if (port_number == url::PORT_INVALID)
     return ProxyServer();
 
@@ -58,8 +58,8 @@
 
 // static
 ProxyServer ProxyServer::FromSchemeHostAndPort(Scheme scheme,
-                                               base::StringPiece host,
-                                               absl::optional<uint16_t> port) {
+                                               std::string_view host,
+                                               std::optional<uint16_t> port) {
   // Create INVALID proxies directly using `ProxyServer()`.
   DCHECK_NE(scheme, SCHEME_INVALID);
 
@@ -70,7 +70,7 @@
   // canonicalization.
   std::string bracketed_host;
   if (!host.empty() && host.front() != '[' &&
-      host.find(":") != base::StringPiece::npos) {
+      host.find(":") != std::string_view::npos) {
     bracketed_host = base::StrCat({"[", host, "]"});
     host = bracketed_host;
   }
@@ -89,7 +89,7 @@
   canonicalized_output.Complete();
 
   // Remove IPv6 literal bracketing, as required by HostPortPair.
-  base::StringPiece unbracketed_host = canonicalized_host;
+  std::string_view unbracketed_host = canonicalized_host;
   if (canonicalized_host.front() == '[' && canonicalized_host.back() == ']')
     unbracketed_host = unbracketed_host.substr(1, unbracketed_host.size() - 2);
 
diff --git a/net/base/proxy_server.h b/net/base/proxy_server.h
index c5cd7a5..266d3b2 100644
--- a/net/base/proxy_server.h
+++ b/net/base/proxy_server.h
@@ -7,14 +7,14 @@
 
 #include <stdint.h>
 
+#include <optional>
 #include <ostream>
 #include <string>
+#include <string_view>
 #include <tuple>
 
-#include "base/strings/string_piece.h"
 #include "net/base/host_port_pair.h"
 #include "net/base/net_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -54,11 +54,11 @@
   // `ProxyServer()` or `Direct()` respectively to create an invalid or direct
   // ProxyServer.
   static ProxyServer FromSchemeHostAndPort(Scheme scheme,
-                                           base::StringPiece host,
-                                           base::StringPiece port_str);
+                                           std::string_view host,
+                                           std::string_view port_str);
   static ProxyServer FromSchemeHostAndPort(Scheme scheme,
-                                           base::StringPiece host,
-                                           absl::optional<uint16_t> port);
+                                           std::string_view host,
+                                           std::optional<uint16_t> port);
 
   // In URL format (with brackets around IPv6 literals). Must not call for
   // ProxyServers without a host (invalid or direct).
diff --git a/net/base/proxy_server_unittest.cc b/net/base/proxy_server_unittest.cc
index 8cf21d0..e489bcf 100644
--- a/net/base/proxy_server_unittest.cc
+++ b/net/base/proxy_server_unittest.cc
@@ -4,10 +4,11 @@
 
 #include "net/base/proxy_server.h"
 
+#include <optional>
+
 #include "base/strings/string_number_conversions.h"
 #include "net/base/proxy_string_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace net {
 
@@ -22,7 +23,7 @@
   const struct {
     const ProxyServer::Scheme input_scheme;
     const char* const input_host;
-    const absl::optional<uint16_t> input_port;
+    const std::optional<uint16_t> input_port;
     const char* const input_port_str;
     const char* const expected_host;
     const uint16_t expected_port;
@@ -63,11 +64,11 @@
       {ProxyServer::SCHEME_SOCKS5, "foopy", 111, "111", "foopy", 111},
 
       // Default ports
-      {ProxyServer::SCHEME_HTTP, "foopy", absl::nullopt, "", "foopy", 80},
-      {ProxyServer::SCHEME_HTTPS, "foopy", absl::nullopt, "", "foopy", 443},
-      {ProxyServer::SCHEME_QUIC, "foopy", absl::nullopt, "", "foopy", 443},
-      {ProxyServer::SCHEME_SOCKS4, "foopy", absl::nullopt, "", "foopy", 1080},
-      {ProxyServer::SCHEME_SOCKS5, "foopy", absl::nullopt, "", "foopy", 1080},
+      {ProxyServer::SCHEME_HTTP, "foopy", std::nullopt, "", "foopy", 80},
+      {ProxyServer::SCHEME_HTTPS, "foopy", std::nullopt, "", "foopy", 443},
+      {ProxyServer::SCHEME_QUIC, "foopy", std::nullopt, "", "foopy", 443},
+      {ProxyServer::SCHEME_SOCKS4, "foopy", std::nullopt, "", "foopy", 1080},
+      {ProxyServer::SCHEME_SOCKS5, "foopy", std::nullopt, "", "foopy", 1080},
   };
 
   for (size_t i = 0; i < std::size(tests); ++i) {
diff --git a/net/base/proxy_string_util.cc b/net/base/proxy_string_util.cc
index 9b8d5cf..e93eb065 100644
--- a/net/base/proxy_string_util.cc
+++ b/net/base/proxy_string_util.cc
@@ -5,10 +5,10 @@
 #include "net/base/proxy_string_util.h"
 
 #include <string>
+#include <string_view>
 
 #include "base/notreached.h"
 #include "base/strings/strcat.h"
-#include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "net/base/proxy_server.h"
 #include "net/base/url_util.h"
@@ -22,7 +22,7 @@
 // Parses the proxy type from a PAC string, to a ProxyServer::Scheme.
 // This mapping is case-insensitive. If no type could be matched
 // returns SCHEME_INVALID.
-ProxyServer::Scheme GetSchemeFromPacTypeInternal(base::StringPiece type) {
+ProxyServer::Scheme GetSchemeFromPacTypeInternal(std::string_view type) {
   if (base::EqualsCaseInsensitiveASCII(type, "proxy"))
     return ProxyServer::SCHEME_HTTP;
   if (base::EqualsCaseInsensitiveASCII(type, "socks")) {
@@ -46,7 +46,7 @@
 }
 
 ProxyServer FromSchemeHostAndPort(ProxyServer::Scheme scheme,
-                                  base::StringPiece host_and_port) {
+                                  std::string_view host_and_port) {
   // Trim leading/trailing space.
   host_and_port = HttpUtil::TrimLWS(host_and_port);
 
@@ -72,7 +72,7 @@
     return ProxyServer();
   }
 
-  base::StringPiece hostname =
+  std::string_view hostname =
       host_and_port.substr(hostname_component.begin, hostname_component.len);
 
   // Reject inputs like "foo:". /url parsing and canonicalization code generally
@@ -80,7 +80,7 @@
   // Chrome has traditionally disallowed it in proxy specifications.
   if (port_component.is_valid() && port_component.is_empty())
     return ProxyServer();
-  base::StringPiece port =
+  std::string_view port =
       port_component.is_nonempty()
           ? host_and_port.substr(port_component.begin, port_component.len)
           : "";
@@ -88,24 +88,23 @@
   return ProxyServer::FromSchemeHostAndPort(scheme, hostname, port);
 }
 
-std::string ConstructHostPortString(base::StringPiece hostname, uint16_t port) {
+std::string ConstructHostPortString(std::string_view hostname, uint16_t port) {
   DCHECK(!hostname.empty());
   DCHECK((hostname.front() == '[' && hostname.back() == ']') ||
-         hostname.find(":") == base::StringPiece::npos);
+         hostname.find(":") == std::string_view::npos);
 
   return base::StrCat({hostname, ":", base::NumberToString(port)});
 }
 
 }  // namespace
 
-ProxyChain PacResultElementToProxyChain(base::StringPiece pac_result_element) {
+ProxyChain PacResultElementToProxyChain(std::string_view pac_result_element) {
   // TODO(https://crbug.com/1491092): Support parsing multi-hop proxy chains
   // from PAC scripts.
   return ProxyChain(PacResultElementToProxyServer(pac_result_element));
 }
 
-ProxyServer PacResultElementToProxyServer(
-    base::StringPiece pac_result_element) {
+ProxyServer PacResultElementToProxyServer(std::string_view pac_result_element) {
   // Trim the leading/trailing whitespace.
   pac_result_element = HttpUtil::TrimLWS(pac_result_element);
 
@@ -168,12 +167,12 @@
   }
 }
 
-ProxyChain ProxyUriToProxyChain(base::StringPiece uri,
+ProxyChain ProxyUriToProxyChain(std::string_view uri,
                                 ProxyServer::Scheme default_scheme) {
   return ProxyChain(ProxyUriToProxyServer(uri, default_scheme));
 }
 
-ProxyServer ProxyUriToProxyServer(base::StringPiece uri,
+ProxyServer ProxyUriToProxyServer(std::string_view uri,
                                   ProxyServer::Scheme default_scheme) {
   // We will default to |default_scheme| if no scheme specifier was given.
   ProxyServer::Scheme scheme = default_scheme;
@@ -183,7 +182,7 @@
 
   // Check for [<scheme> "://"]
   size_t colon = uri.find(':');
-  if (colon != base::StringPiece::npos && uri.size() - colon >= 3 &&
+  if (colon != std::string_view::npos && uri.size() - colon >= 3 &&
       uri[colon + 1] == '/' && uri[colon + 2] == '/') {
     scheme = GetSchemeFromUriScheme(uri.substr(0, colon));
     uri = uri.substr(colon + 3);  // Skip past the "://"
@@ -224,7 +223,7 @@
   }
 }
 
-ProxyServer::Scheme GetSchemeFromUriScheme(base::StringPiece scheme) {
+ProxyServer::Scheme GetSchemeFromUriScheme(std::string_view scheme) {
   if (base::EqualsCaseInsensitiveASCII(scheme, "http"))
     return ProxyServer::SCHEME_HTTP;
   if (base::EqualsCaseInsensitiveASCII(scheme, "socks4"))
diff --git a/net/base/proxy_string_util.h b/net/base/proxy_string_util.h
index f6aec67..3b0ef675 100644
--- a/net/base/proxy_string_util.h
+++ b/net/base/proxy_string_util.h
@@ -6,8 +6,8 @@
 #define NET_BASE_PROXY_STRING_UTIL_H_
 
 #include <string>
+#include <string_view>
 
-#include "base/strings/string_piece.h"
 #include "net/base/net_export.h"
 #include "net/base/proxy_chain.h"
 #include "net/base/proxy_server.h"
@@ -49,9 +49,9 @@
 //   "QUIC foopy:123"   {scheme=QUIC, host="foopy", port=123}
 //   "BLAH xxx:xx"      INVALID
 NET_EXPORT ProxyChain
-PacResultElementToProxyChain(base::StringPiece pac_result_element);
+PacResultElementToProxyChain(std::string_view pac_result_element);
 NET_EXPORT ProxyServer
-PacResultElementToProxyServer(base::StringPiece pac_result_element);
+PacResultElementToProxyServer(std::string_view pac_result_element);
 NET_EXPORT std::string ProxyChainToPacResultElement(
     const ProxyChain& proxy_chain);
 NET_EXPORT std::string ProxyServerToPacResultElement(
@@ -89,18 +89,17 @@
 //   "quic://foopy:17"  {scheme=QUIC, host="foopy", port=17}
 //   "direct://"        {scheme=DIRECT}
 //   "foopy:X"          INVALID -- bad port.
-NET_EXPORT ProxyChain ProxyUriToProxyChain(base::StringPiece uri,
+NET_EXPORT ProxyChain ProxyUriToProxyChain(std::string_view uri,
                                            ProxyServer::Scheme default_scheme);
 NET_EXPORT ProxyServer
-ProxyUriToProxyServer(base::StringPiece uri,
-                      ProxyServer::Scheme default_scheme);
+ProxyUriToProxyServer(std::string_view uri, ProxyServer::Scheme default_scheme);
 NET_EXPORT std::string ProxyServerToProxyUri(const ProxyServer& proxy_server);
 
 // Parses the proxy scheme from the non-standard URI scheme string
 // representation used in `ProxyUriToProxyServer()` and
 // `ProxyServerToProxyUri()`. If no type could be matched, returns
 // SCHEME_INVALID.
-NET_EXPORT ProxyServer::Scheme GetSchemeFromUriScheme(base::StringPiece scheme);
+NET_EXPORT ProxyServer::Scheme GetSchemeFromUriScheme(std::string_view scheme);
 
 }  // namespace net
 
diff --git a/net/base/registry_controlled_domains/get_domain_and_registry_fuzzer.cc b/net/base/registry_controlled_domains/get_domain_and_registry_fuzzer.cc
index 31caf31d..441bb07 100644
--- a/net/base/registry_controlled_domains/get_domain_and_registry_fuzzer.cc
+++ b/net/base/registry_controlled_domains/get_domain_and_registry_fuzzer.cc
@@ -5,7 +5,8 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#include "base/strings/string_piece.h"
+#include <string_view>
+
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 #include "url/gurl.h"
 
@@ -14,11 +15,11 @@
   // Call GetDomainAndRegistry() twice - once with each filter type to ensure
   // both code paths are exercised.
   net::registry_controlled_domains::GetDomainAndRegistry(
-      base::StringPiece(reinterpret_cast<const char*>(data), size),
+      std::string_view(reinterpret_cast<const char*>(data), size),
       net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
 
   net::registry_controlled_domains::GetDomainAndRegistry(
-      base::StringPiece(reinterpret_cast<const char*>(data), size),
+      std::string_view(reinterpret_cast<const char*>(data), size),
       net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
 
   return 0;
diff --git a/net/base/registry_controlled_domains/registry_controlled_domain.cc b/net/base/registry_controlled_domains/registry_controlled_domain.cc
index f83f9ac..425b469 100644
--- a/net/base/registry_controlled_domains/registry_controlled_domain.cc
+++ b/net/base/registry_controlled_domains/registry_controlled_domain.cc
@@ -46,10 +46,10 @@
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 
 #include <ostream>
+#include <string_view>
 
 #include "base/check_op.h"
 #include "base/notreached.h"
-#include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "net/base/lookup_string_in_fixed_set.h"
@@ -80,7 +80,7 @@
 
 // This version assumes we already removed leading dots from host as well as the
 // last trailing dot if it had one.
-size_t GetRegistryLengthInTrimmedHost(base::StringPiece host,
+size_t GetRegistryLengthInTrimmedHost(std::string_view host,
                                       UnknownRegistryFilter unknown_filter,
                                       PrivateRegistryFilter private_filter) {
   size_t length;
@@ -95,8 +95,9 @@
     // If we allow unknown registries, return the length of last subcomponent.
     if (unknown_filter == INCLUDE_UNKNOWN_REGISTRIES) {
       const size_t last_dot = host.find_last_of('.');
-      if (last_dot != base::StringPiece::npos)
+      if (last_dot != std::string_view::npos) {
         return host.size() - last_dot - 1;
+      }
     }
     return 0;
   }
@@ -116,8 +117,9 @@
         host.find_last_of('.', host.size() - length - 2);
 
     // If no preceding dot, then the host is the registry itself, so return 0.
-    if (preceding_dot == base::StringPiece::npos)
+    if (preceding_dot == std::string_view::npos) {
       return 0;
+    }
 
     // Return suffix size plus size of subdomain.
     return host.size() - preceding_dot - 1;
@@ -125,7 +127,7 @@
 
   if (type & kDafsaExceptionRule) {
     size_t first_dot = host.find_first_of('.', host.size() - length);
-    if (first_dot == base::StringPiece::npos) {
+    if (first_dot == std::string_view::npos) {
       // If we get here, we had an exception rule with no dots (e.g.
       // "!foo").  This would only be valid if we had a corresponding
       // wildcard rule, which would have to be "*".  But we explicitly
@@ -149,7 +151,7 @@
   return length;
 }
 
-size_t GetRegistryLengthImpl(base::StringPiece host,
+size_t GetRegistryLengthImpl(std::string_view host,
                              UnknownRegistryFilter unknown_filter,
                              PrivateRegistryFilter private_filter) {
   if (host.empty())
@@ -157,8 +159,9 @@
 
   // Skip leading dots.
   const size_t host_check_begin = host.find_first_not_of('.');
-  if (host_check_begin == base::StringPiece::npos)
+  if (host_check_begin == std::string_view::npos) {
     return 0;  // Host is only dots.
+  }
 
   // A single trailing dot isn't relevant in this determination, but does need
   // to be included in the final returned length.
@@ -176,8 +179,8 @@
   return length + host.size() - host_check_end;
 }
 
-base::StringPiece GetDomainAndRegistryImpl(
-    base::StringPiece host,
+std::string_view GetDomainAndRegistryImpl(
+    std::string_view host,
     PrivateRegistryFilter private_filter) {
   CHECK(!host.empty());
 
@@ -185,7 +188,7 @@
   const size_t registry_length =
       GetRegistryLengthImpl(host, INCLUDE_UNKNOWN_REGISTRIES, private_filter);
   if ((registry_length == std::string::npos) || (registry_length == 0))
-    return base::StringPiece();  // No registry.
+    return std::string_view();  // No registry.
   // The "2" in this next line is 1 for the dot, plus a 1-char minimum preceding
   // subcomponent length.
   CHECK_GE(host.length(), 2u);
@@ -205,20 +208,20 @@
 // StringPiece that references the underlying string of the passed-in |gurl|.
 // TODO(pkalinnikov): Eliminate this helper by exposing StringPiece as the
 // interface type for all the APIs.
-base::StringPiece GetDomainAndRegistryAsStringPiece(
-    base::StringPiece host,
+std::string_view GetDomainAndRegistryAsStringPiece(
+    std::string_view host,
     PrivateRegistryFilter filter) {
   if (host.empty() || url::HostIsIPAddress(host))
-    return base::StringPiece();
+    return std::string_view();
   return GetDomainAndRegistryImpl(host, filter);
 }
 
 // These two functions append the given string as-is to the given output,
 // converting to UTF-8 if necessary.
-void AppendInvalidString(base::StringPiece str, url::CanonOutput* output) {
+void AppendInvalidString(std::string_view str, url::CanonOutput* output) {
   output->Append(str);
 }
-void AppendInvalidString(base::StringPiece16 str, url::CanonOutput* output) {
+void AppendInvalidString(std::u16string_view str, url::CanonOutput* output) {
   output->Append(base::UTF16ToUTF8(str));
 }
 
@@ -295,8 +298,8 @@
     // but it doesn't work across dots so this is safe.
 
     // Expected canonical registry controlled domain.
-    base::StringPiece canonical_rcd(&canonical_host[canonical_rcd_begin],
-                                    canonical_rcd_len);
+    std::string_view canonical_rcd(&canonical_host[canonical_rcd_begin],
+                                   canonical_rcd_len);
 
     for (int current_try = static_cast<int>(mapping.original_end) - 1;
          current_try >= static_cast<int>(mapping.original_begin);
@@ -322,8 +325,8 @@
   return canonical_rcd_len;
 }
 
-bool SameDomainOrHost(base::StringPiece host1,
-                      base::StringPiece host2,
+bool SameDomainOrHost(std::string_view host1,
+                      std::string_view host2,
                       PrivateRegistryFilter filter) {
   // Quickly reject cases where either host is empty.
   if (host1.empty() || host2.empty())
@@ -335,7 +338,7 @@
     return true;
 
   // Check for a domain and registry match.
-  base::StringPiece domain1 = GetDomainAndRegistryAsStringPiece(host1, filter);
+  std::string_view domain1 = GetDomainAndRegistryAsStringPiece(host1, filter);
   return !domain1.empty() &&
          (domain1 == GetDomainAndRegistryAsStringPiece(host2, filter));
 }
@@ -353,7 +356,7 @@
   return std::string(GetDomainAndRegistryAsStringPiece(origin.host(), filter));
 }
 
-std::string GetDomainAndRegistry(base::StringPiece host,
+std::string GetDomainAndRegistry(std::string_view host,
                                  PrivateRegistryFilter filter) {
   url::CanonHostInfo host_info;
   const std::string canon_host(CanonicalizeHost(host, &host_info));
@@ -376,7 +379,7 @@
 }
 
 bool SameDomainOrHost(const url::Origin& origin1,
-                      const absl::optional<url::Origin>& origin2,
+                      const std::optional<url::Origin>& origin2,
                       PrivateRegistryFilter filter) {
   return origin2.has_value() &&
          SameDomainOrHost(origin1, origin2.value(), filter);
@@ -396,7 +399,7 @@
                                private_filter);
 }
 
-bool HostHasRegistryControlledDomain(base::StringPiece host,
+bool HostHasRegistryControlledDomain(std::string_view host,
                                      UnknownRegistryFilter unknown_filter,
                                      PrivateRegistryFilter private_filter) {
   url::CanonHostInfo host_info;
@@ -425,7 +428,7 @@
   return (rcd_length != 0) && (rcd_length != std::string::npos);
 }
 
-size_t GetCanonicalHostRegistryLength(base::StringPiece canon_host,
+size_t GetCanonicalHostRegistryLength(std::string_view canon_host,
                                       UnknownRegistryFilter unknown_filter,
                                       PrivateRegistryFilter private_filter) {
 #ifndef NDEBUG
@@ -437,14 +440,14 @@
   return GetRegistryLengthImpl(canon_host, unknown_filter, private_filter);
 }
 
-size_t PermissiveGetHostRegistryLength(base::StringPiece host,
+size_t PermissiveGetHostRegistryLength(std::string_view host,
                                        UnknownRegistryFilter unknown_filter,
                                        PrivateRegistryFilter private_filter) {
   return DoPermissiveGetHostRegistryLength(host, unknown_filter,
                                            private_filter);
 }
 
-size_t PermissiveGetHostRegistryLength(base::StringPiece16 host,
+size_t PermissiveGetHostRegistryLength(std::u16string_view host,
                                        UnknownRegistryFilter unknown_filter,
                                        PrivateRegistryFilter private_filter) {
   return DoPermissiveGetHostRegistryLength(host, unknown_filter,
diff --git a/net/base/registry_controlled_domains/registry_controlled_domain.h b/net/base/registry_controlled_domains/registry_controlled_domain.h
index 076215b..24ada49e 100644
--- a/net/base/registry_controlled_domains/registry_controlled_domain.h
+++ b/net/base/registry_controlled_domains/registry_controlled_domain.h
@@ -115,11 +115,11 @@
 
 #include <stddef.h>
 
+#include <optional>
 #include <string>
+#include <string_view>
 
-#include "base/strings/string_piece.h"
 #include "net/base/net_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 class GURL;
 
@@ -190,7 +190,7 @@
 // Like the GURL / Origin versions, but takes a host (which is canonicalized
 // internally). Prefer either the GURL or Origin variants instead of this one
 // to avoid needing to re-canonicalize the host.
-NET_EXPORT std::string GetDomainAndRegistry(base::StringPiece host,
+NET_EXPORT std::string GetDomainAndRegistry(std::string_view host,
                                             PrivateRegistryFilter filter);
 
 // These convenience functions return true if the two GURLs or Origins both have
@@ -207,7 +207,7 @@
                                  PrivateRegistryFilter filter);
 // Note: this returns false if |origin2| is not set.
 NET_EXPORT bool SameDomainOrHost(const url::Origin& origin1,
-                                 const absl::optional<url::Origin>& origin2,
+                                 const std::optional<url::Origin>& origin2,
                                  PrivateRegistryFilter filter);
 NET_EXPORT bool SameDomainOrHost(const GURL& gurl,
                                  const url::Origin& origin,
@@ -245,7 +245,7 @@
 // host names like "*.google.com" as long as it has a valid registry-controlled
 // portion (see PermissiveGetHostRegistryLength for particulars).
 NET_EXPORT bool HostHasRegistryControlledDomain(
-    base::StringPiece host,
+    std::string_view host,
     UnknownRegistryFilter unknown_filter,
     PrivateRegistryFilter private_filter);
 
@@ -255,7 +255,7 @@
 //
 // If you have a non-canonical host name, use the "Permissive" version instead.
 NET_EXPORT size_t
-GetCanonicalHostRegistryLength(base::StringPiece canon_host,
+GetCanonicalHostRegistryLength(std::string_view canon_host,
                                UnknownRegistryFilter unknown_filter,
                                PrivateRegistryFilter private_filter);
 
@@ -285,11 +285,11 @@
 // return std::string::npos like GetRegistryLength() for empty input, but
 // because invalid portions are skipped, it won't return npos in any other case.
 NET_EXPORT size_t
-PermissiveGetHostRegistryLength(base::StringPiece host,
+PermissiveGetHostRegistryLength(std::string_view host,
                                 UnknownRegistryFilter unknown_filter,
                                 PrivateRegistryFilter private_filter);
 NET_EXPORT size_t
-PermissiveGetHostRegistryLength(base::StringPiece16 host,
+PermissiveGetHostRegistryLength(std::u16string_view host,
                                 UnknownRegistryFilter unknown_filter,
                                 PrivateRegistryFilter private_filter);
 
diff --git a/net/base/registry_controlled_domains/registry_controlled_domain_unittest.cc b/net/base/registry_controlled_domains/registry_controlled_domain_unittest.cc
index 6d43956e..fc13cd1 100644
--- a/net/base/registry_controlled_domains/registry_controlled_domain_unittest.cc
+++ b/net/base/registry_controlled_domains/registry_controlled_domain_unittest.cc
@@ -57,14 +57,14 @@
                            INCLUDE_PRIVATE_REGISTRIES);
 }
 
-size_t PermissiveGetHostRegistryLength(base::StringPiece host) {
+size_t PermissiveGetHostRegistryLength(std::string_view host) {
   return PermissiveGetHostRegistryLength(host, EXCLUDE_UNKNOWN_REGISTRIES,
                                          EXCLUDE_PRIVATE_REGISTRIES);
 }
 
 // Only called when using ICU (avoids unused static function error).
 #if !BUILDFLAG(USE_PLATFORM_ICU_ALTERNATIVES)
-size_t PermissiveGetHostRegistryLength(base::StringPiece16 host) {
+size_t PermissiveGetHostRegistryLength(std::u16string_view host) {
   return PermissiveGetHostRegistryLength(host, EXCLUDE_UNKNOWN_REGISTRIES,
                                          EXCLUDE_PRIVATE_REGISTRIES);
 }
diff --git a/net/base/scheme_host_port_matcher_rule.cc b/net/base/scheme_host_port_matcher_rule.cc
index b041b045..e789dab 100644
--- a/net/base/scheme_host_port_matcher_rule.cc
+++ b/net/base/scheme_host_port_matcher_rule.cc
@@ -30,8 +30,8 @@
 // static
 std::unique_ptr<SchemeHostPortMatcherRule>
 SchemeHostPortMatcherRule::FromUntrimmedRawString(
-    base::StringPiece raw_untrimmed) {
-  base::StringPiece raw =
+    std::string_view raw_untrimmed) {
+  std::string_view raw =
       base::TrimWhitespaceASCII(raw_untrimmed, base::TRIM_ALL);
 
   // Extract any scheme-restriction.
diff --git a/net/base/scheme_host_port_matcher_rule.h b/net/base/scheme_host_port_matcher_rule.h
index 5a5b6d5..93b52b1 100644
--- a/net/base/scheme_host_port_matcher_rule.h
+++ b/net/base/scheme_host_port_matcher_rule.h
@@ -7,8 +7,8 @@
 
 #include <memory>
 #include <string>
+#include <string_view>
 
-#include "base/strings/string_piece.h"
 #include "net/base/cronet_buildflags.h"
 #include "net/base/ip_address.h"
 #include "net/base/ip_endpoint.h"
@@ -33,7 +33,7 @@
   // this header file. Types with other serializations will need to be handled
   // by the caller.
   static std::unique_ptr<SchemeHostPortMatcherRule> FromUntrimmedRawString(
-      base::StringPiece raw_untrimmed);
+      std::string_view raw_untrimmed);
 
   // Evaluates the rule against |url|.
   virtual SchemeHostPortMatcherResult Evaluate(const GURL& url) const = 0;
diff --git a/net/base/schemeful_site.cc b/net/base/schemeful_site.cc
index d5335cb..b2d0a58 100644
--- a/net/base/schemeful_site.cc
+++ b/net/base/schemeful_site.cc
@@ -97,11 +97,11 @@
   return true;
 }
 
-absl::optional<SchemefulSite> SchemefulSite::CreateIfHasRegisterableDomain(
+std::optional<SchemefulSite> SchemefulSite::CreateIfHasRegisterableDomain(
     const url::Origin& origin) {
   ObtainASiteResult result = ObtainASite(origin);
   if (!result.used_registerable_domain)
-    return absl::nullopt;
+    return std::nullopt;
   return SchemefulSite(std::move(result));
 }
 
@@ -158,27 +158,27 @@
 }
 
 // static
-absl::optional<SchemefulSite> SchemefulSite::DeserializeWithNonce(
+std::optional<SchemefulSite> SchemefulSite::DeserializeWithNonce(
     base::PassKey<NetworkAnonymizationKey>,
     const std::string& value) {
   return DeserializeWithNonce(value);
 }
 
 // static
-absl::optional<SchemefulSite> SchemefulSite::DeserializeWithNonce(
+std::optional<SchemefulSite> SchemefulSite::DeserializeWithNonce(
     const std::string& value) {
-  absl::optional<url::Origin> result = url::Origin::Deserialize(value);
+  std::optional<url::Origin> result = url::Origin::Deserialize(value);
   if (!result)
-    return absl::nullopt;
+    return std::nullopt;
   return SchemefulSite(result.value());
 }
 
-absl::optional<std::string> SchemefulSite::SerializeWithNonce(
+std::optional<std::string> SchemefulSite::SerializeWithNonce(
     base::PassKey<NetworkAnonymizationKey>) {
   return SerializeWithNonce();
 }
 
-absl::optional<std::string> SchemefulSite::SerializeWithNonce() {
+std::optional<std::string> SchemefulSite::SerializeWithNonce() {
   return site_as_origin_.SerializeWithNonceAndInitIfNeeded();
 }
 
diff --git a/net/base/schemeful_site.h b/net/base/schemeful_site.h
index c4919ca..dd2334a 100644
--- a/net/base/schemeful_site.h
+++ b/net/base/schemeful_site.h
@@ -5,13 +5,13 @@
 #ifndef NET_BASE_SCHEMEFUL_SITE_H_
 #define NET_BASE_SCHEMEFUL_SITE_H_
 
+#include <optional>
 #include <ostream>
 #include <string>
 
 #include "base/gtest_prod_util.h"
 #include "base/types/pass_key.h"
 #include "net/base/net_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/origin.h"
 
 class GURL;
@@ -84,7 +84,7 @@
   static bool FromWire(const url::Origin& site_as_origin, SchemefulSite* out);
 
   // Creates a SchemefulSite iff the passed-in origin has a registerable domain.
-  static absl::optional<SchemefulSite> CreateIfHasRegisterableDomain(
+  static std::optional<SchemefulSite> CreateIfHasRegisterableDomain(
       const url::Origin&);
 
   // If the scheme is ws or wss, it is converted to http or https, respectively.
@@ -117,14 +117,14 @@
 
   // Deserializes a string obtained from `SerializeWithNonce()` to a
   // `SchemefulSite`. Returns nullopt if the value was invalid in any way.
-  static absl::optional<SchemefulSite> DeserializeWithNonce(
+  static std::optional<SchemefulSite> DeserializeWithNonce(
       base::PassKey<NetworkAnonymizationKey>,
       const std::string& value);
 
   // Returns a serialized version of `site_as_origin_`. For an opaque
   // `site_as_origin_`, this serializes with the nonce.  See
   // `url::origin::SerializeWithNonce()` for usage information.
-  absl::optional<std::string> SerializeWithNonce(
+  std::optional<std::string> SerializeWithNonce(
       base::PassKey<NetworkAnonymizationKey>);
 
   bool opaque() const { return site_as_origin_.opaque(); }
@@ -190,13 +190,13 @@
 
   // Deserializes a string obtained from `SerializeWithNonce()` to a
   // `SchemefulSite`. Returns nullopt if the value was invalid in any way.
-  static absl::optional<SchemefulSite> DeserializeWithNonce(
+  static std::optional<SchemefulSite> DeserializeWithNonce(
       const std::string& value);
 
   // Returns a serialized version of `site_as_origin_`. For an opaque
   // `site_as_origin_`, this serializes with the nonce.  See
   // `url::origin::SerializeWithNonce()` for usage information.
-  absl::optional<std::string> SerializeWithNonce();
+  std::optional<std::string> SerializeWithNonce();
 
   // Returns whether `this` and `other` share a host or registrable domain.
   // Should NOT be used to check equality or equivalence. This is only used
diff --git a/net/base/schemeful_site_fuzzer.cc b/net/base/schemeful_site_fuzzer.cc
index 15c25bd..fc574464 100644
--- a/net/base/schemeful_site_fuzzer.cc
+++ b/net/base/schemeful_site_fuzzer.cc
@@ -5,13 +5,14 @@
 #include "net/base/schemeful_site.h"
 
 #include <stdlib.h>
+
 #include <iostream>
+#include <optional>
 #include <string>
 
 #include "testing/libfuzzer/proto/lpm_interface.h"
 #include "testing/libfuzzer/proto/url.pb.h"
 #include "testing/libfuzzer/proto/url_proto_converter.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -31,7 +32,7 @@
 
   net::SchemefulSite site(origin);
 
-  absl::optional<net::SchemefulSite> site_with_registrable_domain =
+  std::optional<net::SchemefulSite> site_with_registrable_domain =
       net::SchemefulSite::CreateIfHasRegisterableDomain(origin);
 
   if (site_with_registrable_domain) {
diff --git a/net/base/schemeful_site_unittest.cc b/net/base/schemeful_site_unittest.cc
index 3f2d239..4d574b1 100644
--- a/net/base/schemeful_site_unittest.cc
+++ b/net/base/schemeful_site_unittest.cc
@@ -173,7 +173,7 @@
   ASSERT_TRUE(IsStandardSchemeWithNetworkHost("network"));
   ASSERT_FALSE(IsStandardSchemeWithNetworkHost("non-network"));
 
-  absl::optional<SchemefulSite> network_host_site =
+  std::optional<SchemefulSite> network_host_site =
       SchemefulSite::CreateIfHasRegisterableDomain(
           url::Origin::Create(GURL("network://site.example.test:1337")));
   EXPECT_TRUE(network_host_site.has_value());
@@ -182,7 +182,7 @@
   EXPECT_EQ("example.test",
             network_host_site->GetInternalOriginForTesting().host());
 
-  absl::optional<SchemefulSite> non_network_host_site_null =
+  std::optional<SchemefulSite> non_network_host_site_null =
       SchemefulSite::CreateIfHasRegisterableDomain(
           url::Origin::Create(GURL("non-network://site.example.test")));
   EXPECT_FALSE(non_network_host_site_null.has_value());
@@ -240,7 +240,7 @@
     SCOPED_TRACE(site.GetDebugString());
     EXPECT_FALSE(site.GetInternalOriginForTesting().opaque());
 
-    absl::optional<SchemefulSite> deserialized_site =
+    std::optional<SchemefulSite> deserialized_site =
         SchemefulSite::Deserialize(site.Serialize());
     EXPECT_TRUE(deserialized_site);
     EXPECT_EQ(site, deserialized_site);
@@ -262,7 +262,7 @@
     SCOPED_TRACE(test_case.site.GetDebugString());
     std::string serialized_site = test_case.site.SerializeFileSiteWithHost();
     EXPECT_EQ(test_case.expected, serialized_site);
-    absl::optional<SchemefulSite> deserialized_site =
+    std::optional<SchemefulSite> deserialized_site =
         SchemefulSite::Deserialize(serialized_site);
     EXPECT_TRUE(deserialized_site);
     EXPECT_EQ(test_case.site, deserialized_site);
@@ -287,7 +287,7 @@
       SchemefulSite(GURL("data:text/html,<body>Hello World</body>"))};
 
   for (auto& site : kTestSites) {
-    absl::optional<SchemefulSite> deserialized_site =
+    std::optional<SchemefulSite> deserialized_site =
         SchemefulSite::DeserializeWithNonce(*site.SerializeWithNonce());
     EXPECT_TRUE(deserialized_site);
     EXPECT_EQ(site, *deserialized_site);
@@ -340,7 +340,7 @@
        }) {
     url::Origin origin = url::Origin::Create(GURL(site));
     EXPECT_EQ(SchemefulSite::CreateIfHasRegisterableDomain(origin),
-              absl::nullopt)
+              std::nullopt)
         << "site = \"" << site << "\"";
   }
 }
diff --git a/net/base/test_completion_callback.h b/net/base/test_completion_callback.h
index 7a0e788b..b851cf16 100644
--- a/net/base/test_completion_callback.h
+++ b/net/base/test_completion_callback.h
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <memory>
+#include <optional>
 #include <utility>
 
 #include "base/compiler_specific.h"
@@ -15,7 +16,6 @@
 #include "base/memory/raw_ptr.h"
 #include "net/base/completion_once_callback.h"
 #include "net/base/net_errors.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 //-----------------------------------------------------------------------------
 // completion callback helper
diff --git a/net/base/transport_info.cc b/net/base/transport_info.cc
index c35bb9b..73c70f07 100644
--- a/net/base/transport_info.cc
+++ b/net/base/transport_info.cc
@@ -13,7 +13,7 @@
 
 namespace net {
 
-base::StringPiece TransportTypeToString(TransportType type) {
+std::string_view TransportTypeToString(TransportType type) {
   switch (type) {
     case TransportType::kDirect:
       return "TransportType::kDirect";
diff --git a/net/base/transport_info.h b/net/base/transport_info.h
index 21fd94a7..dcc2e80a 100644
--- a/net/base/transport_info.h
+++ b/net/base/transport_info.h
@@ -7,8 +7,8 @@
 
 #include <iosfwd>
 #include <string>
+#include <string_view>
 
-#include "base/strings/string_piece.h"
 #include "net/base/ip_endpoint.h"
 #include "net/base/net_export.h"
 
@@ -28,7 +28,7 @@
 
 // Returns a string representation of the given transport type.
 // The returned StringPiece is static, has no lifetime restrictions.
-NET_EXPORT base::StringPiece TransportTypeToString(TransportType type);
+NET_EXPORT std::string_view TransportTypeToString(TransportType type);
 
 // Describes a network transport.
 struct NET_EXPORT TransportInfo {
diff --git a/net/base/unescape_url_component_fuzzer.cc b/net/base/unescape_url_component_fuzzer.cc
index 257b66e0..3e2622e 100644
--- a/net/base/unescape_url_component_fuzzer.cc
+++ b/net/base/unescape_url_component_fuzzer.cc
@@ -13,7 +13,7 @@
 
 // Entry point for LibFuzzer.
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-  base::StringPiece path(reinterpret_cast<const char*>(data), size);
+  std::string_view path(reinterpret_cast<const char*>(data), size);
   for (int i = 0; i <= kMaxUnescapeRule; i++) {
     base::UnescapeURLComponent(path, static_cast<base::UnescapeRule::Type>(i));
   }
diff --git a/net/base/upload_file_element_reader_unittest.cc b/net/base/upload_file_element_reader_unittest.cc
index 24709f2..c103459 100644
--- a/net/base/upload_file_element_reader_unittest.cc
+++ b/net/base/upload_file_element_reader_unittest.cc
@@ -47,7 +47,7 @@
     ASSERT_TRUE(
         base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &temp_file_path_));
     ASSERT_TRUE(base::WriteFile(
-        temp_file_path_, base::StringPiece(bytes_.data(), bytes_.size())));
+        temp_file_path_, std::string_view(bytes_.data(), bytes_.size())));
 
     reader_ =
         CreateReader(0, std::numeric_limits<uint64_t>::max(), base::Time());
diff --git a/net/base/url_search_params.cc b/net/base/url_search_params.cc
index 62c5aa4b..9215bc4 100644
--- a/net/base/url_search_params.cc
+++ b/net/base/url_search_params.cc
@@ -6,11 +6,11 @@
 
 #include <algorithm>
 #include <string>
+#include <string_view>
 #include <utility>
 #include <vector>
 
 #include "base/containers/cxx20_erase_vector.h"
-#include "base/strings/string_piece.h"
 #include "base/strings/utf_string_conversions.h"
 #include "net/base/url_util.h"
 #include "url/gurl.h"
diff --git a/net/base/url_util.cc b/net/base/url_util.cc
index 1355259..3b5199f7 100644
--- a/net/base/url_util.cc
+++ b/net/base/url_util.cc
@@ -12,17 +12,18 @@
 #include <ws2tcpip.h>
 #endif
 
+#include <optional>
+#include <string_view>
+
 #include "base/check_op.h"
 #include "base/containers/fixed_flat_set.h"
 #include "base/strings/escape.h"
 #include "base/strings/strcat.h"
-#include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "net/base/ip_address.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/scheme_host_port.h"
 #include "url/url_canon.h"
@@ -41,7 +42,7 @@
   return ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9'));
 }
 
-bool IsNormalizedLocalhostTLD(base::StringPiece host) {
+bool IsNormalizedLocalhostTLD(std::string_view host) {
   return base::EndsWith(host, ".localhost",
                         base::CompareCase::INSENSITIVE_ASCII);
 }
@@ -50,7 +51,7 @@
 // unescaped" to a valid UTF-8 string, return that string, as UTF-16. Otherwise,
 // convert it as-is to UTF-16. "Safely unescaped" is defined as having no
 // escaped character between '0x00' and '0x1F', inclusive.
-std::u16string UnescapeIdentityString(base::StringPiece escaped_text) {
+std::u16string UnescapeIdentityString(std::string_view escaped_text) {
   std::string unescaped_text;
   if (base::UnescapeBinaryURLComponentSafe(
           escaped_text, false /* fail_on_path_separators */, &unescaped_text)) {
@@ -66,8 +67,8 @@
 }  // namespace
 
 GURL AppendQueryParameter(const GURL& url,
-                          base::StringPiece name,
-                          base::StringPiece value) {
+                          std::string_view name,
+                          std::string_view value) {
   std::string query(url.query());
 
   if (!query.empty())
@@ -81,8 +82,8 @@
 }
 
 GURL AppendOrReplaceQueryParameter(const GURL& url,
-                                   base::StringPiece name,
-                                   absl::optional<base::StringPiece> value) {
+                                   std::string_view name,
+                                   std::optional<std::string_view> value) {
   bool replaced = false;
   std::string param_name = base::EscapeQueryParamValue(name, true);
   bool should_keep_param = value.has_value();
@@ -91,13 +92,13 @@
   if (should_keep_param)
     param_value = base::EscapeQueryParamValue(value.value(), true);
 
-  const base::StringPiece input = url.query_piece();
+  const std::string_view input = url.query_piece();
   url::Component cursor(0, input.size());
   std::string output;
   url::Component key_range, value_range;
   while (url::ExtractQueryKeyValue(input.data(), &cursor, &key_range,
                                    &value_range)) {
-    const base::StringPiece key = input.substr(key_range.begin, key_range.len);
+    const std::string_view key = input.substr(key_range.begin, key_range.len);
     std::string key_value_pair;
     // Check |replaced| as only the first pair should be replaced.
     if (!replaced && key == param_name) {
@@ -126,7 +127,7 @@
   return url.ReplaceComponents(replacements);
 }
 
-GURL AppendOrReplaceRef(const GURL& url, const base::StringPiece& ref) {
+GURL AppendOrReplaceRef(const GURL& url, const std::string_view& ref) {
   GURL::Replacements replacements;
   replacements.SetRefStr(ref);
   return url.ReplaceComponents(replacements);
@@ -142,18 +143,18 @@
 
 QueryIterator::~QueryIterator() = default;
 
-base::StringPiece QueryIterator::GetKey() const {
+std::string_view QueryIterator::GetKey() const {
   DCHECK(!at_end_);
   if (key_.is_nonempty())
-    return base::StringPiece(url_->spec()).substr(key_.begin, key_.len);
-  return base::StringPiece();
+    return std::string_view(url_->spec()).substr(key_.begin, key_.len);
+  return std::string_view();
 }
 
-base::StringPiece QueryIterator::GetValue() const {
+std::string_view QueryIterator::GetValue() const {
   DCHECK(!at_end_);
   if (value_.is_nonempty())
-    return base::StringPiece(url_->spec()).substr(value_.begin, value_.len);
-  return base::StringPiece();
+    return std::string_view(url_->spec()).substr(value_.begin, value_.len);
+  return std::string_view();
 }
 
 const std::string& QueryIterator::GetUnescapedValue() {
@@ -182,7 +183,7 @@
 }
 
 bool GetValueForKeyInQuery(const GURL& url,
-                           base::StringPiece search_key,
+                           std::string_view search_key,
                            std::string* out_value) {
   for (QueryIterator it(url); !it.IsAtEnd(); it.Advance()) {
     if (it.GetKey() == search_key) {
@@ -193,7 +194,7 @@
   return false;
 }
 
-bool ParseHostAndPort(base::StringPiece input, std::string* host, int* port) {
+bool ParseHostAndPort(std::string_view input, std::string* host, int* port) {
   if (input.empty())
     return false;
 
@@ -280,8 +281,8 @@
   return scheme_host_port.host();
 }
 
-std::string TrimEndingDot(base::StringPiece host) {
-  base::StringPiece host_trimmed = host;
+std::string TrimEndingDot(std::string_view host) {
+  std::string_view host_trimmed = host;
   size_t len = host_trimmed.length();
   if (len > 1 && host_trimmed[len - 1] == '.') {
     host_trimmed.remove_suffix(1);
@@ -293,14 +294,14 @@
   return url.has_host() ? TrimEndingDot(url.host_piece()) : url.spec();
 }
 
-std::string GetSuperdomain(base::StringPiece domain) {
+std::string GetSuperdomain(std::string_view domain) {
   size_t dot_pos = domain.find('.');
   if (dot_pos == std::string::npos)
     return "";
   return std::string(domain.substr(dot_pos + 1));
 }
 
-bool IsSubdomainOf(base::StringPiece subdomain, base::StringPiece superdomain) {
+bool IsSubdomainOf(std::string_view subdomain, std::string_view superdomain) {
   // Subdomain must be identical or have strictly more labels than the
   // superdomain.
   if (subdomain.length() <= superdomain.length())
@@ -314,7 +315,7 @@
   return subdomain.back() == '.';
 }
 
-std::string CanonicalizeHost(base::StringPiece host,
+std::string CanonicalizeHost(std::string_view host,
                              url::CanonHostInfo* host_info) {
   // Try to canonicalize the host.
   const url::Component raw_host_component(0, static_cast<int>(host.length()));
@@ -347,7 +348,7 @@
   return canon_host;
 }
 
-bool IsCanonicalizedHostCompliant(base::StringPiece host) {
+bool IsCanonicalizedHostCompliant(std::string_view host) {
   if (host.empty() || host.size() > 254 ||
       (host.back() != '.' && host.size() == 254)) {
     return false;
@@ -387,7 +388,7 @@
   return most_recent_component_started_alphanumeric;
 }
 
-bool IsHostnameNonUnique(base::StringPiece hostname) {
+bool IsHostnameNonUnique(std::string_view hostname) {
   // CanonicalizeHost requires surrounding brackets to parse an IPv6 address.
   const std::string host_or_ip = hostname.find(':') != std::string::npos
                                      ? base::StrCat({"[", hostname, "]"})
@@ -436,7 +437,7 @@
   return HostStringIsLocalhost(url.HostNoBracketsPiece());
 }
 
-bool HostStringIsLocalhost(base::StringPiece host) {
+bool HostStringIsLocalhost(std::string_view host) {
   IPAddress ip_address;
   if (ip_address.AssignFromIPLiteral(host))
     return ip_address.IsLoopback();
@@ -463,7 +464,7 @@
   return url.ReplaceComponents(replace_scheme);
 }
 
-bool IsStandardSchemeWithNetworkHost(base::StringPiece scheme) {
+bool IsStandardSchemeWithNetworkHost(std::string_view scheme) {
   // file scheme is special. Windows file share origins can have network hosts.
   if (scheme == url::kFileScheme)
     return true;
@@ -488,7 +489,7 @@
   return IsGoogleHost(url.host_piece());
 }
 
-bool IsGoogleHost(base::StringPiece host) {
+bool IsGoogleHost(std::string_view host) {
   static const char* kGoogleHostSuffixes[] = {
       ".google.com",
       ".youtube.com",
@@ -513,12 +514,12 @@
   return false;
 }
 
-bool IsGoogleHostWithAlpnH3(base::StringPiece host) {
+bool IsGoogleHostWithAlpnH3(std::string_view host) {
   return base::EqualsCaseInsensitiveASCII(host, "google.com") ||
          base::EqualsCaseInsensitiveASCII(host, "www.google.com");
 }
 
-bool IsLocalHostname(base::StringPiece host) {
+bool IsLocalHostname(std::string_view host) {
   // Remove any trailing '.'.
   if (!host.empty() && *host.rbegin() == '.')
     host.remove_suffix(1);
@@ -527,7 +528,7 @@
          IsNormalizedLocalhostTLD(host);
 }
 
-std::string UnescapePercentEncodedUrl(base::StringPiece input) {
+std::string UnescapePercentEncodedUrl(std::string_view input) {
   std::string result(input);
   // Replace any 0x2B (+) with 0x20 (SP).
   for (char& c : result) {
diff --git a/net/base/url_util.h b/net/base/url_util.h
index 3038f208..9819e54 100644
--- a/net/base/url_util.h
+++ b/net/base/url_util.h
@@ -10,12 +10,12 @@
 #ifndef NET_BASE_URL_UTIL_H_
 #define NET_BASE_URL_UTIL_H_
 
+#include <optional>
 #include <string>
+#include <string_view>
 
 #include "base/memory/raw_ref.h"
-#include "base/strings/string_piece.h"
 #include "net/base/net_export.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/third_party/mozilla/url_parse.h"
 
 class GURL;
@@ -38,14 +38,14 @@
 // AppendQueryParameter(GURL("http://example.com?x=y"), "name", "value").spec()
 // => "http://example.com?x=y&name=value"
 NET_EXPORT GURL AppendQueryParameter(const GURL& url,
-                                     base::StringPiece name,
-                                     base::StringPiece value);
+                                     std::string_view name,
+                                     std::string_view value);
 
 // Returns a new GURL by appending or replacing the given query parameter name
 // and the value. If `name` appears more than once, only the first name-value
 // pair is replaced. Unsafe characters in the name and the value are escaped
 // like %XX%XX. The original query component is preserved if it's present.
-// Using `absl::nullopt` for `value` will remove the `name` parameter.
+// Using `std::nullopt` for `value` will remove the `name` parameter.
 //
 // Examples:
 //
@@ -56,12 +56,12 @@
 //     GURL("http://example.com?x=y&name=old"), "name", "new").spec()
 // => "http://example.com?x=y&name=new"
 // AppendOrReplaceQueryParameter(
-//     GURL("http://example.com?x=y&name=old"), "name", absl::nullopt).spec()
+//     GURL("http://example.com?x=y&name=old"), "name", std::nullopt).spec()
 // => "http://example.com?x=y&"
 NET_EXPORT GURL
 AppendOrReplaceQueryParameter(const GURL& url,
-                              base::StringPiece name,
-                              absl::optional<base::StringPiece> value);
+                              std::string_view name,
+                              std::optional<std::string_view> value);
 
 // Returns a new GURL by appending the provided ref (also named fragment).
 // Unsafe characters are escaped. The original fragment is replaced
@@ -76,12 +76,12 @@
 //     GURL("http://example.com#ref"), "ref2").spec()
 // => "http://example.com#ref2"
 NET_EXPORT GURL AppendOrReplaceRef(const GURL& url,
-                                   const base::StringPiece& ref);
+                                   const std::string_view& ref);
 
 // Iterates over the key-value pairs in the query portion of |url|.
-// NOTE: QueryIterator stores reference to |url| and creates base::StringPiece
+// NOTE: QueryIterator stores reference to |url| and creates std::string_view
 // instances which refer to the data inside |url| query. Therefore |url| must
-// outlive QueryIterator and all base::StringPiece objects returned from GetKey
+// outlive QueryIterator and all std::string_view objects returned from GetKey
 // and GetValue methods.
 class NET_EXPORT QueryIterator {
  public:
@@ -90,8 +90,8 @@
   QueryIterator& operator=(const QueryIterator&) = delete;
   ~QueryIterator();
 
-  base::StringPiece GetKey() const;
-  base::StringPiece GetValue() const;
+  std::string_view GetKey() const;
+  std::string_view GetValue() const;
   const std::string& GetUnescapedValue();
 
   bool IsAtEnd() const;
@@ -110,7 +110,7 @@
 // key is found and sets |out_value| to the unescaped value for the key.
 // Returns false if the key is not found.
 NET_EXPORT bool GetValueForKeyInQuery(const GURL& url,
-                                      base::StringPiece search_key,
+                                      std::string_view search_key,
                                       std::string* out_value);
 
 // Splits an input of the form <host>[":"<port>] into its consitituent parts.
@@ -123,7 +123,7 @@
 //   [::1]:90 and [::1]
 //
 // The resultant |*host| in both cases will be "::1" (not bracketed).
-NET_EXPORT bool ParseHostAndPort(base::StringPiece input,
+NET_EXPORT bool ParseHostAndPort(std::string_view input,
                                  std::string* host,
                                  int* port);
 
@@ -139,7 +139,7 @@
     const url::SchemeHostPort& scheme_host_port);
 
 // Returns the hostname by trimming the ending dot, if one exists.
-NET_EXPORT std::string TrimEndingDot(base::StringPiece host);
+NET_EXPORT std::string TrimEndingDot(std::string_view host);
 
 // Returns either the host from |url|, or, if the host is empty, the full spec.
 NET_EXPORT std::string GetHostOrSpecFromURL(const GURL& url);
@@ -158,18 +158,18 @@
 // GetSuperdomain("example.net") -> "net"
 // GetSuperdomain("littlebox") -> ""
 // GetSuperdomain("127.0.0.1") -> "0.0.1"
-NET_EXPORT std::string GetSuperdomain(base::StringPiece domain);
+NET_EXPORT std::string GetSuperdomain(std::string_view domain);
 
 // Returns whether |subdomain| is a subdomain of (or identical to)
 // |superdomain|, if both are hostnames (not IP addresses -- for which this
 // function is nonsensical). Does not consider the Public Suffix List.
 // Returns true if both input strings are empty.
-NET_EXPORT bool IsSubdomainOf(base::StringPiece subdomain,
-                              base::StringPiece superdomain);
+NET_EXPORT bool IsSubdomainOf(std::string_view subdomain,
+                              std::string_view superdomain);
 
 // Canonicalizes |host| and returns it.  Also fills |host_info| with
 // IP address information.  |host_info| must not be NULL.
-NET_EXPORT std::string CanonicalizeHost(base::StringPiece host,
+NET_EXPORT std::string CanonicalizeHost(std::string_view host,
                                         url::CanonHostInfo* host_info);
 
 // Returns true if |host| is not an IP address and is compliant with a set of
@@ -185,12 +185,12 @@
 //
 // NOTE: You should only pass in hosts that have been returned from
 // CanonicalizeHost(), or you may not get accurate results.
-NET_EXPORT bool IsCanonicalizedHostCompliant(base::StringPiece host);
+NET_EXPORT bool IsCanonicalizedHostCompliant(std::string_view host);
 
 // Returns true if |hostname| contains a non-registerable or non-assignable
 // domain name (eg: a gTLD that has not been assigned by IANA) or an IP address
 // that falls in an range reserved for non-publicly routable networks.
-NET_EXPORT bool IsHostnameNonUnique(base::StringPiece hostname);
+NET_EXPORT bool IsHostnameNonUnique(std::string_view hostname);
 
 // Returns true if the host part of |url| is a local host name according to
 // HostStringIsLocalhost.
@@ -204,7 +204,7 @@
 // Note that this function does not check for IP addresses other than
 // the above, although other IP addresses may point to the local
 // machine.
-NET_EXPORT bool HostStringIsLocalhost(base::StringPiece host);
+NET_EXPORT bool HostStringIsLocalhost(std::string_view host);
 
 // Strip the portions of |url| that aren't core to the network request.
 //   - user name / password
@@ -220,7 +220,7 @@
 // Returns whether the given url scheme is of a standard scheme type that can
 // have hostnames representing domains (i.e. network hosts).
 // See url::SchemeType.
-NET_EXPORT bool IsStandardSchemeWithNetworkHost(base::StringPiece scheme);
+NET_EXPORT bool IsStandardSchemeWithNetworkHost(std::string_view scheme);
 
 // Extracts the unescaped username/password from |url|, saving the results
 // into |*username| and |*password|.
@@ -234,21 +234,21 @@
 
 // Returns true if |host| is the hostname of a Google server. This should only
 // be used for histograms and shouldn't be used to affect behavior.
-NET_EXPORT_PRIVATE bool IsGoogleHost(base::StringPiece host);
+NET_EXPORT_PRIVATE bool IsGoogleHost(std::string_view host);
 
 // Returns true if |host| is the hostname of a Google server and HTTPS DNS
 // record of |host| is expected to indicate H3 support. This should only be used
 // for histograms and shouldn't be used to affect behavior.
-NET_EXPORT_PRIVATE bool IsGoogleHostWithAlpnH3(base::StringPiece host);
+NET_EXPORT_PRIVATE bool IsGoogleHostWithAlpnH3(std::string_view host);
 
 // This function tests |host| to see if it is of any local hostname form.
 // |host| is normalized before being tested.
-NET_EXPORT_PRIVATE bool IsLocalHostname(base::StringPiece host);
+NET_EXPORT_PRIVATE bool IsLocalHostname(std::string_view host);
 
 // The notion of unescaping used in the application/x-www-form-urlencoded
 // parser. https://url.spec.whatwg.org/#concept-urlencoded-parser
 NET_EXPORT_PRIVATE std::string UnescapePercentEncodedUrl(
-    base::StringPiece input);
+    std::string_view input);
 
 }  // namespace net
 
diff --git a/net/base/url_util_unittest.cc b/net/base/url_util_unittest.cc
index 8cd6065c..35269b79 100644
--- a/net/base/url_util_unittest.cc
+++ b/net/base/url_util_unittest.cc
@@ -4,12 +4,12 @@
 
 #include "net/base/url_util.h"
 
+#include <optional>
 #include <ostream>
 
 #include "base/format_macros.h"
 #include "base/strings/utf_string_conversions.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/scheme_host_port.h"
 #include "url/url_util.h"
@@ -96,20 +96,20 @@
   EXPECT_EQ("http://example.com/path?abc=xyz",
             AppendOrReplaceQueryParameter(
                 GURL("http://example.com/path?name=value&abc=xyz"), "name",
-                absl::nullopt)
+                std::nullopt)
                 .spec());
 
   // Removes the name-value pair from the URL.
   EXPECT_EQ("http://example.com/path?",
             AppendOrReplaceQueryParameter(
                 GURL("http://example.com/path?existing=one"), "existing",
-                absl::nullopt)
+                std::nullopt)
                 .spec());
 
   // Removes the first name-value pair.
   EXPECT_EQ("http://example.com/path?c=d&e=f",
             AppendOrReplaceQueryParameter(
-                GURL("http://example.com/path?a=b&c=d&e=f"), "a", absl::nullopt)
+                GURL("http://example.com/path?a=b&c=d&e=f"), "a", std::nullopt)
                 .spec());
 
   // Removes a name-value pair in between two query params.
@@ -117,14 +117,14 @@
       "http://example.com/path?existing=one&hello=world",
       AppendOrReplaceQueryParameter(
           GURL("http://example.com/path?existing=one&replace=sure&hello=world"),
-          "replace", absl::nullopt)
+          "replace", std::nullopt)
           .spec());
 
   // Removes the last name-value pair.
   EXPECT_EQ("http://example.com/path?existing=one",
             AppendOrReplaceQueryParameter(
                 GURL("http://example.com/path?existing=one&replace=sure"),
-                "replace", absl::nullopt)
+                "replace", std::nullopt)
                 .spec());
 
   // Removing a name-value pair with unsafe characters included. The
@@ -133,14 +133,14 @@
             AppendOrReplaceQueryParameter(
                 GURL("http://example.com/"
                      "path?existing=one&na+me=v.alue%3D&hello=world"),
-                "na me", absl::nullopt)
+                "na me", std::nullopt)
                 .spec());
 
   // Does nothing if the provided query param key does not exist.
   EXPECT_EQ("http://example.com/path?existing=one&name=old",
             AppendOrReplaceQueryParameter(
                 GURL("http://example.com/path?existing=one&name=old"), "old",
-                absl::nullopt)
+                std::nullopt)
                 .spec());
 
   // Remove the value of first parameter with this name only.
@@ -148,7 +148,7 @@
       "http://example.com/path?existing=one&name=old",
       AppendOrReplaceQueryParameter(
           GURL("http://example.com/path?name=something&existing=one&name=old"),
-          "name", absl::nullopt)
+          "name", std::nullopt)
           .spec());
 
   // Preserve the content of the original params regardless of our failure to
@@ -159,7 +159,7 @@
       AppendOrReplaceQueryParameter(
           GURL("http://example.com/path?bar&name=old&left=&"
                "=right&=&&name=again"),
-          "name", absl::nullopt)
+          "name", std::nullopt)
           .spec());
 }
 
@@ -910,7 +910,7 @@
 
 TEST(UrlUtilTest, GoogleHostWithAlpnH3) {
   struct {
-    base::StringPiece host;
+    std::string_view host;
     bool expected_output;
   } test_cases[] = {
       {"google.com", true},        {"www.google.com", true},
diff --git a/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.cc b/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.cc
index 92ad36d8..1e14dbd 100644
--- a/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.cc
+++ b/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.cc
@@ -11,6 +11,7 @@
 #include "base/pickle.h"
 #include "base/strings/strcat.h"
 #include "base/task/sequenced_task_runner.h"
+#include "base/types/expected_macros.h"
 #include "net/base/network_isolation_key.h"
 #include "net/extras/shared_dictionary/shared_dictionary_isolation_key.h"
 #include "net/extras/sqlite/sqlite_persistent_store_backend_base.h"
@@ -563,10 +564,7 @@
     return base::unexpected(error);
   }
 
-  SizeOrError total_dictionary_count_result = GetTotalDictionaryCount();
-  if (!total_dictionary_count_result.has_value()) {
-    return base::unexpected(total_dictionary_count_result.error());
-  }
+  ASSIGN_OR_RETURN(uint64_t total_dictionary_count, GetTotalDictionaryCount());
 
   if (!transaction.Commit()) {
     return base::unexpected(Error::kFailedToCommitTransaction);
@@ -575,7 +573,7 @@
       id, replaced_disk_cache_key_token,
       std::set<base::UnguessableToken>(evicted_disk_cache_key_tokens.begin(),
                                        evicted_disk_cache_key_tokens.end()),
-      total_dictionary_size, total_dictionary_count_result.value()});
+      total_dictionary_size, total_dictionary_count});
 }
 
 SQLitePersistentSharedDictionaryStore::Error
@@ -624,35 +622,32 @@
   CHECK(primary_keys_out->empty());
   CHECK(tokens_out->empty());
   CHECK_EQ(0, *total_size_of_candidates_out);
-  SizeOrError size_per_site = GetDictionarySizePerSite(top_frame_site);
-  if (!size_per_site.has_value()) {
-    return size_per_site.error();
-  }
-  SizeOrError count_per_site = GetDictionaryCountPerSite(top_frame_site);
-  if (!count_per_site.has_value()) {
-    return count_per_site.error();
-  }
+
+  ASSIGN_OR_RETURN(uint64_t size_per_site,
+                   GetDictionarySizePerSite(top_frame_site));
+  ASSIGN_OR_RETURN(uint64_t count_per_site,
+                   GetDictionaryCountPerSite(top_frame_site));
 
   base::UmaHistogramMemoryKB(
       base::StrCat({kHistogramPrefix, "DictionarySizeKBPerSiteWhenAdded"}),
-      size_per_site.value());
+      size_per_site);
   base::UmaHistogramCounts1000(
       base::StrCat({kHistogramPrefix, "DictionaryCountPerSiteWhenAdded"}),
-      count_per_site.value());
+      count_per_site);
 
-  if ((max_size_per_site == 0 || size_per_site.value() <= max_size_per_site) &&
-      count_per_site.value() <= max_count_per_site) {
+  if ((max_size_per_site == 0 || size_per_site <= max_size_per_site) &&
+      count_per_site <= max_count_per_site) {
     return Error::kOk;
   }
 
   uint64_t to_be_removed_count = 0;
-  if (count_per_site.value() > max_count_per_site) {
-    to_be_removed_count = count_per_site.value() - max_count_per_site;
+  if (count_per_site > max_count_per_site) {
+    to_be_removed_count = count_per_site - max_count_per_site;
   }
 
   int64_t to_be_removed_size = 0;
-  if (max_size_per_site != 0 && size_per_site.value() > max_size_per_site) {
-    to_be_removed_size = size_per_site.value() - max_size_per_site;
+  if (max_size_per_site != 0 && size_per_site > max_size_per_site) {
+    to_be_removed_size = size_per_site - max_size_per_site;
   }
   static constexpr char kQuery[] =
       // clang-format off
@@ -1340,17 +1335,9 @@
     std::vector<int64_t>* primary_keys_out,
     std::vector<base::UnguessableToken>* tokens_out,
     int64_t* total_size_after_eviction_out) {
-  SizeOrError total_dictionary_size_result = GetTotalDictionarySizeImpl();
-  if (!total_dictionary_size_result.has_value()) {
-    return total_dictionary_size_result.error();
-  }
-  uint64_t total_dictionary_size = total_dictionary_size_result.value();
-
-  SizeOrError total_dictionary_count_result = GetTotalDictionaryCount();
-  if (!total_dictionary_count_result.has_value()) {
-    return total_dictionary_count_result.error();
-  }
-  uint64_t total_dictionary_count = total_dictionary_count_result.value();
+  ASSIGN_OR_RETURN(uint64_t total_dictionary_size,
+                   GetTotalDictionarySizeImpl());
+  ASSIGN_OR_RETURN(uint64_t total_dictionary_count, GetTotalDictionaryCount());
 
   if ((cache_max_size == 0 || total_dictionary_size <= cache_max_size) &&
       total_dictionary_count <= cache_max_count) {
@@ -1442,20 +1429,19 @@
     return Error::kFailedToBeginTransaction;
   }
 
-  base::CheckedNumeric<int64_t> checked_total_dictionary_size;
+  base::CheckedNumeric<int64_t> checked_total_deleted_dictionary_size;
   for (const auto& token : disk_cache_key_tokens) {
-    SizeOrError result = DeleteDictionaryByDiskCacheToken(token);
-    if (!result.has_value()) {
-      return result.error();
-    }
-    checked_total_dictionary_size += result.value();
+    ASSIGN_OR_RETURN(uint64_t deleted_dictionary_size,
+                     DeleteDictionaryByDiskCacheToken(token));
+    checked_total_deleted_dictionary_size += deleted_dictionary_size;
   }
 
-  int64_t deleted_size = checked_total_dictionary_size.ValueOrDie();
-  if (deleted_size != 0u) {
+  int64_t total_deleted_dictionary_size =
+      checked_total_deleted_dictionary_size.ValueOrDie();
+  if (total_deleted_dictionary_size != 0) {
     uint64_t total_dictionary_size = 0;
-    Error error = UpdateTotalDictionarySizeInMetaTable(-deleted_size,
-                                                       &total_dictionary_size);
+    Error error = UpdateTotalDictionarySizeInMetaTable(
+        -total_deleted_dictionary_size, &total_dictionary_size);
     if (error != Error::kOk) {
       return error;
     }
@@ -1624,13 +1610,10 @@
     UpdateTotalDictionarySizeInMetaTable(int64_t size_delta,
                                          uint64_t* total_dictionary_size_out) {
   CHECK(background_task_runner()->RunsTasksInCurrentSequence());
-  SizeOrError total_dictionary_size_or_error = GetTotalDictionarySizeImpl();
-  if (!total_dictionary_size_or_error.has_value()) {
-    return total_dictionary_size_or_error.error();
-  }
-
+  ASSIGN_OR_RETURN(uint64_t total_dictionary_size,
+                   GetTotalDictionarySizeImpl());
   base::CheckedNumeric<uint64_t> checked_total_dictionary_size =
-      total_dictionary_size_or_error.value();
+      total_dictionary_size;
   checked_total_dictionary_size += size_delta;
   if (!checked_total_dictionary_size.IsValid()) {
     LOG(ERROR) << "Invalid total_dict_size detected.";
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 1bf2cc8..eb743d4 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -1900,6 +1900,8 @@
 
 void HttpNetworkTransaction::ResetConnectionAndRequestForResend(
     RetryReason retry_reason) {
+  // TODO:(crbug.com/1495705): Remove this CHECK after fixing the bug.
+  CHECK(request_);
   base::UmaHistogramEnumeration(
       IsGoogleHostWithAlpnH3(url_.host())
           ? "Net.NetworkTransactionH3SupportedGoogleHost.RetryReason"
diff --git a/printing/test_printing_context.cc b/printing/test_printing_context.cc
index 8eca2dfa..c3e8397a 100644
--- a/printing/test_printing_context.cc
+++ b/printing/test_printing_context.cc
@@ -136,6 +136,10 @@
     const PrinterSettings& printer_settings) {
   DCHECK(!in_print_job_);
 
+  if (update_printer_settings_fails_) {
+    return mojom::ResultCode::kFailed;
+  }
+
   // The printer name is to be embedded in the printing context's existing
   // settings.
   const std::string& device_name = base::UTF16ToUTF8(settings_->device_name());
diff --git a/printing/test_printing_context.h b/printing/test_printing_context.h
index 1db95b6..494a45c7 100644
--- a/printing/test_printing_context.h
+++ b/printing/test_printing_context.h
@@ -82,6 +82,9 @@
 
   // Enables tests to fail with a failed error.
   void SetNewDocumentFails() { new_document_fails_ = true; }
+  void SetUpdatePrinterSettingsFails() {
+    update_printer_settings_fails_ = true;
+  }
   void SetUseDefaultSettingsFails() { use_default_settings_fails_ = true; }
 
   // Enables tests to fail with a canceled error.
@@ -144,6 +147,7 @@
   bool destination_is_preview_ = false;
 #endif
 
+  bool update_printer_settings_fails_ = false;
   bool use_default_settings_fails_ = false;
   bool ask_user_for_settings_cancel_ = false;
   bool new_document_cancels_ = false;
diff --git a/remoting/host/win/windows_event_logger.cc b/remoting/host/win/windows_event_logger.cc
index 9f7fe92..7b445bdf 100644
--- a/remoting/host/win/windows_event_logger.cc
+++ b/remoting/host/win/windows_event_logger.cc
@@ -7,6 +7,7 @@
 #include <string>
 #include <vector>
 
+#include "base/check.h"
 #include "base/logging.h"
 #include "base/strings/utf_string_conversions.h"
 #include "remoting/host/win/remoting_host_messages.h"
diff --git a/rlz/lib/recursive_cross_process_lock_posix.cc b/rlz/lib/recursive_cross_process_lock_posix.cc
index 844f016..179f0b8 100644
--- a/rlz/lib/recursive_cross_process_lock_posix.cc
+++ b/rlz/lib/recursive_cross_process_lock_posix.cc
@@ -13,6 +13,7 @@
 
 #include <tuple>
 
+#include "base/check.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/posix/eintr_wrapper.h"
diff --git a/services/tracing/perfetto/producer_host.cc b/services/tracing/perfetto/producer_host.cc
index 43dae66..9dd0946 100644
--- a/services/tracing/perfetto/producer_host.cc
+++ b/services/tracing/perfetto/producer_host.cc
@@ -13,6 +13,7 @@
 #include "services/tracing/perfetto/perfetto_service.h"
 #include "services/tracing/public/cpp/perfetto/producer_client.h"
 #include "services/tracing/public/cpp/perfetto/shared_memory.h"
+#include "third_party/perfetto/include/perfetto/ext/tracing/core/client_identity.h"
 #include "third_party/perfetto/include/perfetto/ext/tracing/core/commit_data_request.h"
 #include "third_party/perfetto/include/perfetto/tracing/core/data_source_descriptor.h"
 #include "third_party/perfetto/include/perfetto/tracing/core/trace_config.h"
@@ -50,7 +51,10 @@
 
   // TODO(oysteine): Figure out a uid once we need it.
   producer_endpoint_ = service->ConnectProducer(
-      this, 0 /* uid */, /*pid=*/::perfetto::base::kInvalidPid, name, shm_size,
+      this,
+      perfetto::ClientIdentity(/*uid=*/0,
+                               /*pid=*/perfetto::base::kInvalidPid),
+      name, shm_size,
       /*in_process=*/false,
       perfetto::TracingService::ProducerSMBScrapingMode::kDefault,
       shared_memory_buffer_page_size_bytes, std::move(shm));
diff --git a/services/webnn/public/mojom/webnn_context_provider.mojom b/services/webnn/public/mojom/webnn_context_provider.mojom
index 484d05d..1b1c303 100644
--- a/services/webnn/public/mojom/webnn_context_provider.mojom
+++ b/services/webnn/public/mojom/webnn_context_provider.mojom
@@ -63,6 +63,10 @@
   // executing computational graph, the WebNN graph will be validated and
   // compiled. Initializes the compiled graph for optimal performance of the
   // subsequent graph executions if the initialization is a necessary step.
+  //
+  // TODO(crbug.com/1488162): Remove [Sync] if the standards group decides that
+  // the WebNN sync APIs are not required.
+  [Sync]
   CreateGraph(GraphInfo graph_info) => (CreateGraphResult result);
 };
 
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 1ee35a1..55be7c4f8 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -2171,7 +2171,7 @@
         "bucket": "chromiumos-image-archive",
         "ci_only": true,
         "cros_board": "volteer",
-        "cros_img": "volteer-public/R121-15669.0.0",
+        "cros_img": "volteer-public/R121-15670.0.0",
         "cros_model": "voxel",
         "dut_pool": "chromium",
         "name": "chromeos_integration_tests VOLTEER_PUBLIC_LKGM",
@@ -2185,7 +2185,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "volteer",
-        "cros_img": "volteer-public/R121-15669.0.0",
+        "cros_img": "volteer-public/R121-15670.0.0",
         "cros_model": "voxel",
         "dut_pool": "chromium",
         "name": "lacros_all_tast_tests VOLTEER_PUBLIC_LKGM",
@@ -2530,7 +2530,7 @@
         "autotest_name": "chromium",
         "bucket": "chromiumos-image-archive",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-public/R121-15669.0.0",
+        "cros_img": "jacuzzi-public/R121-15670.0.0",
         "name": "chromeos_integration_tests JACUZZI_PUBLIC_LKGM",
         "test": "chromeos_integration_tests",
         "test_id_prefix": "ninja://chrome/test:chromeos_integration_tests/",
@@ -2540,7 +2540,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-public/R121-15669.0.0",
+        "cros_img": "jacuzzi-public/R121-15670.0.0",
         "name": "lacros_all_tast_tests JACUZZI_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -2570,7 +2570,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "trogdor",
-        "cros_img": "trogdor-public/R121-15669.0.0",
+        "cros_img": "trogdor-public/R121-15670.0.0",
         "name": "lacros_all_tast_tests TROGDOR_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -6096,9 +6096,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6111.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6113.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 121.0.6111.0",
+        "description": "Run with ash-chrome version 121.0.6113.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -6108,8 +6108,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6111.0",
-              "revision": "version:121.0.6111.0"
+              "location": "lacros_version_skew_tests_v121.0.6113.0",
+              "revision": "version:121.0.6113.0"
             }
           ],
           "dimensions": {
@@ -6246,9 +6246,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6111.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6113.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 121.0.6111.0",
+        "description": "Run with ash-chrome version 121.0.6113.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -6258,8 +6258,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6111.0",
-              "revision": "version:121.0.6111.0"
+              "location": "lacros_version_skew_tests_v121.0.6113.0",
+              "revision": "version:121.0.6113.0"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json
index 71e1edb..3973992 100644
--- a/testing/buildbot/chromium.coverage.json
+++ b/testing/buildbot/chromium.coverage.json
@@ -20451,9 +20451,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6111.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6113.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 121.0.6111.0",
+        "description": "Run with ash-chrome version 121.0.6113.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -20463,8 +20463,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6111.0",
-              "revision": "version:121.0.6111.0"
+              "location": "lacros_version_skew_tests_v121.0.6113.0",
+              "revision": "version:121.0.6113.0"
             }
           ],
           "dimensions": {
@@ -20601,9 +20601,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6111.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6113.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 121.0.6111.0",
+        "description": "Run with ash-chrome version 121.0.6113.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -20613,8 +20613,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6111.0",
-              "revision": "version:121.0.6111.0"
+              "location": "lacros_version_skew_tests_v121.0.6113.0",
+              "revision": "version:121.0.6113.0"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 9980210..86802a9a 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -4533,6 +4533,56 @@
       }
     ]
   },
+  "chromeos-jacuzzi-rel-skylab-fyi": {
+    "additional_compile_targets": [
+      "chrome"
+    ],
+    "skylab_tests": [
+      {
+        "autotest_name": "tast.chrome-from-gcs",
+        "cros_board": "jacuzzi",
+        "name": "chrome_all_tast_tests JACUZZI_RELEASE_CHROME_FROM_TLS_LKGM",
+        "shards": 10,
+        "tast_expr": "STUB_STRING_TO_RUN_TAST_TESTS",
+        "test": "chrome_all_tast_tests",
+        "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/",
+        "test_level_retries": 2,
+        "timeout_sec": 21600,
+        "use_lkgm": true,
+        "variant_id": "JACUZZI_RELEASE_CHROME_FROM_TLS_LKGM"
+      },
+      {
+        "autotest_name": "tast.chrome-from-gcs",
+        "ci_only": true,
+        "cros_board": "jacuzzi",
+        "experiment_percentage": 100,
+        "name": "chrome_criticalstaging_tast_tests JACUZZI_RELEASE_CHROME_FROM_TLS_LKGM",
+        "shards": 3,
+        "tast_expr": "STUB_STRING_TO_RUN_TAST_TESTS",
+        "test": "chrome_criticalstaging_tast_tests",
+        "test_id_prefix": "ninja://chromeos:chrome_criticalstaging_tast_tests/",
+        "test_level_retries": 2,
+        "timeout_sec": 7200,
+        "use_lkgm": true,
+        "variant_id": "JACUZZI_RELEASE_CHROME_FROM_TLS_LKGM"
+      },
+      {
+        "autotest_name": "tast.chrome-from-gcs",
+        "ci_only": true,
+        "cros_board": "jacuzzi",
+        "experiment_percentage": 100,
+        "name": "chrome_disabled_tast_tests JACUZZI_RELEASE_CHROME_FROM_TLS_LKGM",
+        "shards": 2,
+        "tast_expr": "STUB_STRING_TO_RUN_TAST_TESTS",
+        "test": "chrome_disabled_tast_tests",
+        "test_id_prefix": "ninja://chromeos:chrome_disabled_tast_tests/",
+        "test_level_retries": 1,
+        "timeout_sec": 7200,
+        "use_lkgm": true,
+        "variant_id": "JACUZZI_RELEASE_CHROME_FROM_TLS_LKGM"
+      }
+    ]
+  },
   "ios-blink-dbg-fyi": {
     "additional_compile_targets": [
       "all"
@@ -41049,7 +41099,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "eve",
-        "cros_img": "eve-public/R121-15669.0.0",
+        "cros_img": "eve-public/R121-15670.0.0",
         "dut_pool": "chromium",
         "name": "lacros_all_tast_tests EVE_PUBLIC_LKGM",
         "public_builder": "cros_test_platform_public",
@@ -41070,7 +41120,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "octopus",
-        "cros_img": "octopus-public/R121-15669.0.0",
+        "cros_img": "octopus-public/R121-15670.0.0",
         "name": "lacros_all_tast_tests OCTOPUS_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -41095,7 +41145,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-public/R121-15669.0.0",
+        "cros_img": "jacuzzi-public/R121-15670.0.0",
         "name": "lacros_all_tast_tests JACUZZI_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -41113,7 +41163,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "trogdor",
-        "cros_img": "trogdor-public/R121-15669.0.0",
+        "cros_img": "trogdor-public/R121-15670.0.0",
         "name": "lacros_all_tast_tests TROGDOR_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -41138,7 +41188,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-public/R121-15669.0.0",
+        "cros_img": "jacuzzi-public/R121-15670.0.0",
         "name": "lacros_all_tast_tests JACUZZI_CQ_PUBLIC_LKGM",
         "public_builder": "cros_test_platform_public",
         "public_builder_bucket": "testplatform-public",
@@ -41158,7 +41208,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "jacuzzi",
-        "cros_img": "jacuzzi-public/R121-15669.0.0",
+        "cros_img": "jacuzzi-public/R121-15670.0.0",
         "name": "lacros_all_tast_tests JACUZZI_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -41176,7 +41226,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "trogdor",
-        "cros_img": "trogdor-public/R121-15669.0.0",
+        "cros_img": "trogdor-public/R121-15670.0.0",
         "name": "lacros_all_tast_tests TROGDOR_PUBLIC_LKGM",
         "resultdb": {
           "enable": true,
@@ -43401,9 +43451,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6111.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6113.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 121.0.6111.0",
+        "description": "Run with ash-chrome version 121.0.6113.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -43412,8 +43462,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6111.0",
-              "revision": "version:121.0.6111.0"
+              "location": "lacros_version_skew_tests_v121.0.6113.0",
+              "revision": "version:121.0.6113.0"
             }
           ],
           "dimensions": {
@@ -43551,9 +43601,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6111.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6113.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 121.0.6111.0",
+        "description": "Run with ash-chrome version 121.0.6113.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -43562,8 +43612,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6111.0",
-              "revision": "version:121.0.6111.0"
+              "location": "lacros_version_skew_tests_v121.0.6113.0",
+              "revision": "version:121.0.6113.0"
             }
           ],
           "dimensions": {
@@ -44860,9 +44910,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6111.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6113.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 121.0.6111.0",
+        "description": "Run with ash-chrome version 121.0.6113.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -44871,8 +44921,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6111.0",
-              "revision": "version:121.0.6111.0"
+              "location": "lacros_version_skew_tests_v121.0.6113.0",
+              "revision": "version:121.0.6113.0"
             }
           ],
           "dimensions": {
@@ -45010,9 +45060,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6111.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6113.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 121.0.6111.0",
+        "description": "Run with ash-chrome version 121.0.6113.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -45021,8 +45071,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6111.0",
-              "revision": "version:121.0.6111.0"
+              "location": "lacros_version_skew_tests_v121.0.6113.0",
+              "revision": "version:121.0.6113.0"
             }
           ],
           "dimensions": {
@@ -45705,9 +45755,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6111.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6113.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 121.0.6111.0",
+        "description": "Run with ash-chrome version 121.0.6113.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -45716,8 +45766,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6111.0",
-              "revision": "version:121.0.6111.0"
+              "location": "lacros_version_skew_tests_v121.0.6113.0",
+              "revision": "version:121.0.6113.0"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index 62b5fd1..b964a5c 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -15822,8 +15822,7 @@
           "--enforce-browser-version",
           "--webgl-conformance-version=2.0.1",
           "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_mac_runtimes.json",
-          "--jobs=4",
-          "--enable-metal-debug-layers"
+          "--jobs=4"
         ],
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
@@ -15863,8 +15862,7 @@
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-gl=angle --use-angle=metal --use-cmd-decoder=passthrough --enable-features=EGLDualGPURendering,ForceHighPerformanceGPUForWebGL",
           "--enforce-browser-version",
           "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl1_conformance_mac_runtimes.json",
-          "--jobs=4",
-          "--enable-metal-debug-layers"
+          "--jobs=4"
         ],
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index 8cb24f1..eaae2dd5 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -16249,12 +16249,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6111.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6113.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 121.0.6111.0",
+        "description": "Run with ash-chrome version 121.0.6113.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -16264,8 +16264,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6111.0",
-              "revision": "version:121.0.6111.0"
+              "location": "lacros_version_skew_tests_v121.0.6113.0",
+              "revision": "version:121.0.6113.0"
             }
           ],
           "dimensions": {
@@ -16419,12 +16419,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6111.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6113.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 121.0.6111.0",
+        "description": "Run with ash-chrome version 121.0.6113.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -16434,8 +16434,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6111.0",
-              "revision": "version:121.0.6111.0"
+              "location": "lacros_version_skew_tests_v121.0.6113.0",
+              "revision": "version:121.0.6113.0"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl
index 9c60acca..d5ecf1d 100644
--- a/testing/buildbot/gn_isolate_map.pyl
+++ b/testing/buildbot/gn_isolate_map.pyl
@@ -987,7 +987,7 @@
   },
   "keyboard_accessory_junit_tests": {
     "label": "//chrome/android/features/keyboard_accessory:keyboard_accessory_junit_tests",
-    "type": "junit_test",
+    "type": "generated_script",
   },
   "keyboard_unittests": {
     "label": "//ash/keyboard/ui:keyboard_unittests",
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index c8777e7..fa7b29ab 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -4711,6 +4711,14 @@
         ],
       },
     },
+    'replacements': {
+      'Mac Pro FYI Release (AMD)': {
+        'args': {
+          # Causes problems on older hardware. crbug.com/1499911.
+          '--enable-metal-debug-layers': None,
+        },
+      },
+    },
   },
   'webgl2_conformance_validating_tests': {
     'remove_from': [
@@ -4782,6 +4790,14 @@
         ],
       },
     },
+    'replacements': {
+      'Mac Pro FYI Release (AMD)': {
+        'args': {
+          # Causes problems on older hardware. crbug.com/1499911.
+          '--enable-metal-debug-layers': None,
+        },
+      },
+    },
   },
   'webgl_conformance_tests': {
     'modifications': {
diff --git a/testing/buildbot/tryserver.chromium.chromiumos.json b/testing/buildbot/tryserver.chromium.chromiumos.json
index 9798d28..d93deb55d 100644
--- a/testing/buildbot/tryserver.chromium.chromiumos.json
+++ b/testing/buildbot/tryserver.chromium.chromiumos.json
@@ -11,7 +11,7 @@
         "bucket": "chromiumos-image-archive",
         "ci_only": true,
         "cros_board": "volteer",
-        "cros_img": "volteer-public/R121-15669.0.0",
+        "cros_img": "volteer-public/R121-15670.0.0",
         "cros_model": "voxel",
         "dut_pool": "chromium",
         "name": "chromeos_integration_tests VOLTEER_PUBLIC_LKGM",
@@ -25,7 +25,7 @@
         "autotest_name": "tast.lacros-from-gcs",
         "bucket": "chromiumos-image-archive",
         "cros_board": "volteer",
-        "cros_img": "volteer-public/R121-15669.0.0",
+        "cros_img": "volteer-public/R121-15670.0.0",
         "cros_model": "voxel",
         "dut_pool": "chromium",
         "name": "lacros_all_tast_tests VOLTEER_PUBLIC_LKGM",
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index f47dcc27..232b261 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -70,16 +70,16 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'identifier': 'Lacros version skew testing ash canary',
-    'description': 'Run with ash-chrome version 121.0.6111.0',
+    'description': 'Run with ash-chrome version 121.0.6113.0',
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6111.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6113.0/test_ash_chrome',
     ],
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v121.0.6111.0',
-          'revision': 'version:121.0.6111.0',
+          'location': 'lacros_version_skew_tests_v121.0.6113.0',
+          'revision': 'version:121.0.6113.0',
         },
       ],
     },
@@ -620,7 +620,7 @@
     'identifier': 'EVE_PUBLIC_LKGM',
     'skylab': {
       'cros_board': 'eve',
-      'cros_img': 'eve-public/R121-15669.0.0',
+      'cros_img': 'eve-public/R121-15670.0.0',
       'bucket': 'chromiumos-image-archive',
       'dut_pool': 'chromium',
       'public_builder': 'cros_test_platform_public',
@@ -694,7 +694,7 @@
     'identifier': 'JACUZZI_PUBLIC_LKGM',
     'skylab': {
       'cros_board': 'jacuzzi',
-      'cros_img': 'jacuzzi-public/R121-15669.0.0',
+      'cros_img': 'jacuzzi-public/R121-15670.0.0',
       'bucket': 'chromiumos-image-archive',
     },
   },
@@ -702,7 +702,7 @@
     'identifier': 'JACUZZI_CQ_PUBLIC_LKGM',
     'skylab': {
       'cros_board': 'jacuzzi',
-      'cros_img': 'jacuzzi-public/R121-15669.0.0',
+      'cros_img': 'jacuzzi-public/R121-15670.0.0',
       'bucket': 'chromiumos-image-archive',
       'public_builder': 'cros_test_platform_public',
       'public_builder_bucket': 'testplatform-public',
@@ -712,7 +712,7 @@
     'identifier': 'TROGDOR_PUBLIC_LKGM',
     'skylab': {
       'cros_board': 'trogdor',
-      'cros_img': 'trogdor-public/R121-15669.0.0',
+      'cros_img': 'trogdor-public/R121-15670.0.0',
       'bucket': 'chromiumos-image-archive',
     },
   },
@@ -720,7 +720,7 @@
     'identifier': 'OCTOPUS_PUBLIC_LKGM',
     'skylab': {
       'cros_board': 'octopus',
-      'cros_img': 'octopus-public/R121-15669.0.0',
+      'cros_img': 'octopus-public/R121-15670.0.0',
       'bucket': 'chromiumos-image-archive',
     },
   },
@@ -799,7 +799,7 @@
     'skylab': {
       'cros_board': 'volteer',
       'cros_model': 'voxel',
-      'cros_img': 'volteer-public/R121-15669.0.0',
+      'cros_img': 'volteer-public/R121-15670.0.0',
       'bucket': 'chromiumos-image-archive',
       'dut_pool': 'chromium',
       'public_builder': 'cros_test_platform_public',
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index dc959fc1..f4baa1ed 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -3432,6 +3432,16 @@
           'isolated_scripts': 'chromeos_isolated_scripts',
         },
       },
+      'chromeos-jacuzzi-rel-skylab-fyi': {
+        'additional_compile_targets': [
+          'chrome',
+        ],
+        'test_suites': {
+          'skylab_tests': 'chromeos_jacuzzi_skylab_tests',
+        },
+        'os_type': 'chromeos',
+      },
+
       'ios-blink-dbg-fyi': {
         'additional_compile_targets': [
           'all'
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 9d172aef..b6612a7 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -7610,6 +7610,33 @@
             ]
         }
     ],
+    "GreySnapshotOptimization": [
+        {
+            "platforms": [
+                "ios"
+            ],
+            "experiments": [
+                {
+                    "name": "EnabledNoImagesInDiskAndCache",
+                    "params": {
+                        "level": "do-not-store-to-disk-and-cache"
+                    },
+                    "enable_features": [
+                        "GreySnapshotOptimization"
+                    ]
+                },
+                {
+                    "name": "EnabledNoImagesInDisk",
+                    "params": {
+                        "level": "do-not-store-to-disk"
+                    },
+                    "enable_features": [
+                        "GreySnapshotOptimization"
+                    ]
+                }
+            ]
+        }
+    ],
     "GridTabSwitcherAndroidAnimations": [
         {
             "platforms": [
@@ -8063,7 +8090,7 @@
             ],
             "experiments": [
                 {
-                    "name": "Enabled_20231004",
+                    "name": "Enabled_20231027",
                     "params": {
                         "prob": "0.05",
                         "survey_cycle_length": "7",
diff --git a/third_party/android_sdk/cipd/build-tools/25.0.2.yaml b/third_party/android_sdk/cipd/build-tools/25.0.2.yaml
deleted file mode 100644
index 81ff919..0000000
--- a/third_party/android_sdk/cipd/build-tools/25.0.2.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2019 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-package: chromium/third_party/android_sdk/public/build-tools/25.0.2
-description: build-tools Android SDK Build Tools
-root: ../../public/
-data:
-  - file: build-tools/25.0.2/lib/dx.jar
-# Some tools inspect their argv0 and don't handle CIPD's symlink structure
-# correctly. Install in copy mode so that they can find the other directories
-# relative to themselves.
-install_mode: copy
diff --git a/third_party/android_sdk/cipd/build-tools/33.0.0.yaml b/third_party/android_sdk/cipd/build-tools/33.0.0.yaml
deleted file mode 100644
index 060a733..0000000
--- a/third_party/android_sdk/cipd/build-tools/33.0.0.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2022 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-package: chromium/third_party/android_sdk/public/build-tools/33.0.0
-description: build-tools Android SDK Build Tools
-root: ../../public/
-data:
-  - dir: build-tools/33.0.0
-# Some tools inspect their argv0 and don't handle CIPD's symlink structure
-# correctly. Install in copy mode so that they can find the other directories
-# relative to themselves.
-install_mode: copy
diff --git a/third_party/android_sdk/cipd/patcher/v4.yaml b/third_party/android_sdk/cipd/patcher/v4.yaml
deleted file mode 100644
index 9c6e8a4..0000000
--- a/third_party/android_sdk/cipd/patcher/v4.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2019 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-package: chromium/third_party/android_sdk/public/patcher/v4
-description: patcher Android SDK Tools library
-root: ../../public/
-data:
-  - dir: patcher/v4
-# Some tools inspect their argv0 and don't handle CIPD's symlink structure
-# correctly. Install in copy mode so that they can find the other directories
-# relative to themselves.
-install_mode: copy
diff --git a/third_party/android_sdk/cipd/platforms/android-33.yaml b/third_party/android_sdk/cipd/platforms/android-33.yaml
deleted file mode 100644
index 5fa00e4f..0000000
--- a/third_party/android_sdk/cipd/platforms/android-33.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2022 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-package: chromium/third_party/android_sdk/public/platforms/android-33
-description: platforms Android SDK Platforms library
-root: ../../public/
-data:
-  - dir: platforms/android-33
-# Some tools inspect their argv0 and don't handle CIPD's symlink structure
-# correctly. Install in copy mode so that they can find the other directories
-# relative to themselves.
-install_mode: copy
diff --git a/third_party/android_sdk/cipd/platforms/android-TiramisuPrivacySandbox.yaml b/third_party/android_sdk/cipd/platforms/android-TiramisuPrivacySandbox.yaml
deleted file mode 100644
index 5f2b1d5..0000000
--- a/third_party/android_sdk/cipd/platforms/android-TiramisuPrivacySandbox.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2022 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-package: chromium/third_party/android_sdk/public/platforms/android-tiramisuprivacysandbox
-description: platforms Android SDK Platforms library
-root: ../../public/
-data:
-  - dir: platforms/android-TiramisuPrivacySandbox
-# Some tools inspect their argv0 and don't handle CIPD's symlink structure
-# correctly. Install in copy mode so that they can find the other directories
-# relative to themselves.
-install_mode: copy
diff --git a/third_party/android_sdk/cipd/sources/android-31.yaml b/third_party/android_sdk/cipd/sources/android-31.yaml
deleted file mode 100644
index 6a1c4f0c..0000000
--- a/third_party/android_sdk/cipd/sources/android-31.yaml
+++ /dev/null
@@ -1,13 +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: chromium/third_party/android_sdk/public/sources/android-31
-description: sources Android SDK Sources library
-root: ../../public/
-data:
-  - dir: sources/android-31
-# Some tools inspect their argv0 and don't handle CIPD's symlink structure
-# correctly. Install in copy mode so that they can find the other directories
-# relative to themselves.
-install_mode: copy
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
index 52cafc8..e990423 100644
--- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl
+++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -9931,6 +9931,13 @@
       # duration in seconds
       array of integer ends
 
+  experimental type AttributionReportingTriggerSpec extends object
+    properties
+      # number instead of integer because not all uint32 can be represented by
+      # int
+      array of number triggerData
+      AttributionReportingEventReportWindows eventReportWindows
+
   experimental type AttributionReportingTriggerDataMatching extends string
     enum
       exact
@@ -9941,7 +9948,7 @@
       Network.TimeSinceEpoch time
       # duration in seconds
       integer expiry
-      AttributionReportingEventReportWindows eventReportWindows
+      array of AttributionReportingTriggerSpec triggerSpecs
       # duration in seconds
       integer aggregatableReportWindow
       AttributionReportingSourceType type
diff --git a/third_party/blink/public/mojom/lcp_critical_path_predictor/lcp_critical_path_predictor.mojom b/third_party/blink/public/mojom/lcp_critical_path_predictor/lcp_critical_path_predictor.mojom
index 79e287cd..544a59e 100644
--- a/third_party/blink/public/mojom/lcp_critical_path_predictor/lcp_critical_path_predictor.mojom
+++ b/third_party/blink/public/mojom/lcp_critical_path_predictor/lcp_critical_path_predictor.mojom
@@ -11,7 +11,10 @@
 interface LCPCriticalPathPredictorHost {
   // `lcp_element_locator` is a LCP ElementLocator information
   // serialized in proto3 binary format.
-  SetLcpElementLocator(mojo_base.mojom.ByteString lcp_element_locator);
+  // `lcp_timing_was_predicted` indicates if `lcp_element_locator` was predicted
+  // as actual LCP.
+  SetLcpElementLocator(mojo_base.mojom.ByteString lcp_element_locator,
+    bool lcp_timing_was_predicted);
 
   // `lcp_influencer_scripts` contain the list of script URLs that affected
   // the LCP element.
diff --git a/third_party/blink/public/mojom/page_state/page_state.mojom b/third_party/blink/public/mojom/page_state/page_state.mojom
index 7ca4574..b88c3fd 100644
--- a/third_party/blink/public/mojom/page_state/page_state.mojom
+++ b/third_party/blink/public/mojom/page_state/page_state.mojom
@@ -89,7 +89,7 @@
 
 [Stable, Extensible, RenamedFrom="content.history.mojom.ScrollRestorationType"]
 enum ScrollRestorationType {
-  kAuto = 0,
+  [Default] kAuto = 0,
   kManual = 1
 };
 
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index c9367bd..e6c74bc 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -471,6 +471,7 @@
 
   deps = [
     ":core",
+    ":element_locator_proto",
     ":generated_testing_idls",
     "//build:chromeos_buildflags",
     "//components/ukm:test_support",
diff --git a/third_party/blink/renderer/core/css/element_rule_collector.cc b/third_party/blink/renderer/core/css/element_rule_collector.cc
index 392c85b..7d65d41 100644
--- a/third_party/blink/renderer/core/css/element_rule_collector.cc
+++ b/third_party/blink/renderer/core/css/element_rule_collector.cc
@@ -49,6 +49,7 @@
 #include "third_party/blink/renderer/core/css/resolver/style_resolver.h"
 #include "third_party/blink/renderer/core/css/resolver/style_resolver_stats.h"
 #include "third_party/blink/renderer/core/css/resolver/style_rule_usage_tracker.h"
+#include "third_party/blink/renderer/core/css/seeker.h"
 #include "third_party/blink/renderer/core/css/selector_checker-inl.h"
 #include "third_party/blink/renderer/core/css/selector_statistics.h"
 #include "third_party/blink/renderer/core/css/style_engine.h"
@@ -164,42 +165,6 @@
   return false;
 }
 
-// Sequentially scans a sorted list of RuleSet::Interval<T> and seeks
-// for the value for a rule (given by its position). Seek() must be called
-// with non-decreasing rule positions, so that we only need to go
-// through the layer list at most once for all Seek() calls.
-template <class T>
-class Seeker {
-  STACK_ALLOCATED();
-
- public:
-  explicit Seeker(const HeapVector<RuleSet::Interval<T>>& intervals)
-      : intervals_(intervals), iter_(intervals_.begin()) {}
-
-  const T* Seek(unsigned rule_position) {
-#if DCHECK_IS_ON()
-    DCHECK_GE(rule_position, last_rule_position_);
-    last_rule_position_ = rule_position;
-#endif
-
-    while (iter_ != intervals_.end() &&
-           iter_->start_position <= rule_position) {
-      ++iter_;
-    }
-    if (iter_ == intervals_.begin()) {
-      return nullptr;
-    }
-    return std::prev(iter_)->value.Get();
-  }
-
- private:
-  const HeapVector<RuleSet::Interval<T>>& intervals_;
-  const RuleSet::Interval<T>* iter_;
-#if DCHECK_IS_ON()
-  unsigned last_rule_position_ = 0;
-#endif
-};
-
 // A wrapper around Seeker<CascadeLayer> that also translates through the layer
 // map.
 class CascadeLayerSeeker {
diff --git a/third_party/blink/renderer/core/css/rule_set.cc b/third_party/blink/renderer/core/css/rule_set.cc
index 5b18578..67e1559 100644
--- a/third_party/blink/renderer/core/css/rule_set.cc
+++ b/third_party/blink/renderer/core/css/rule_set.cc
@@ -41,6 +41,7 @@
 #include "third_party/blink/renderer/core/css/css_selector.h"
 #include "third_party/blink/renderer/core/css/css_selector_list.h"
 #include "third_party/blink/renderer/core/css/robin_hood_map-inl.h"
+#include "third_party/blink/renderer/core/css/seeker.h"
 #include "third_party/blink/renderer/core/css/selector_checker-inl.h"
 #include "third_party/blink/renderer/core/css/selector_checker.h"
 #include "third_party/blink/renderer/core/css/selector_filter.h"
@@ -188,14 +189,31 @@
   // as many as 255 descendant selectors.
   bloom_hash_size_ =
       std::min<uint32_t>(bloom_hash_backing.size() - bloom_hash_pos_, 255);
+
+  // If we've already got the exact same set of hashes in the vector,
+  // we can simply reuse those, saving a bit of memory and cache space.
+  // We only check the trivial case of a tail match; we could go with
+  // something like a full suffix tree solution, but this is simple and
+  // captures most of the benefits. (It is fairly common, especially with
+  // nesting, to have the same sets of parents in consecutive rules.)
+  if (bloom_hash_size_ > 0 && bloom_hash_pos_ >= bloom_hash_size_ &&
+      std::equal(
+          bloom_hash_backing.begin() + bloom_hash_pos_ - bloom_hash_size_,
+          bloom_hash_backing.begin() + bloom_hash_pos_,
+          bloom_hash_backing.begin() + bloom_hash_pos_)) {
+    bloom_hash_backing.resize(bloom_hash_pos_);
+    bloom_hash_pos_ -= bloom_hash_size_;
+  }
 }
 
 void RuleData::MovedToDifferentRuleSet(const Vector<unsigned>& old_backing,
-                                       Vector<unsigned>& new_backing) {
+                                       Vector<unsigned>& new_backing,
+                                       unsigned new_position) {
   unsigned new_pos = new_backing.size();
   new_backing.insert(new_backing.size(), old_backing.data() + bloom_hash_pos_,
                      bloom_hash_size_);
   bloom_hash_pos_ = new_pos;
+  position_ = new_position;
 }
 
 void RuleSet::AddToRuleSet(const AtomicString& key,
@@ -863,16 +881,31 @@
   }
 }
 
+void RuleSet::NewlyAddedFromDifferentRuleSet(const RuleData& old_rule_data,
+                                             const StyleScope* style_scope,
+                                             const RuleSet& old_rule_set,
+                                             RuleData& new_rule_data) {
+  new_rule_data.MovedToDifferentRuleSet(old_rule_set.bloom_hash_backing_,
+                                        bloom_hash_backing_, rule_count_);
+  // We don't bother with container_query_intervals_ and
+  // AddRuleToLayerIntervals() here, since they are not checked in diff
+  // rulesets.
+  AddRuleToIntervals(style_scope, rule_count_, scope_intervals_);
+  ++rule_count_;
+}
+
 void RuleSet::AddFilteredRulesFromOtherBucket(
     const RuleSet& other,
     const HeapVector<RuleData>& src,
     const HeapHashSet<Member<StyleRule>>& only_include,
     HeapVector<RuleData>* dst) {
+  Seeker<StyleScope> scope_seeker(other.scope_intervals_);
   for (const RuleData& rule_data : src) {
     if (IncludeRule(rule_data.Rule(), only_include)) {
       dst->push_back(rule_data);
-      dst->back().MovedToDifferentRuleSet(other.bloom_hash_backing_,
-                                          bloom_hash_backing_);
+      NewlyAddedFromDifferentRuleSet(rule_data,
+                                     scope_seeker.Seek(rule_data.GetPosition()),
+                                     other, dst->back());
     }
   }
 }
@@ -881,22 +914,17 @@
     const RuleSet& other,
     const HeapHashSet<Member<StyleRule>>& only_include) {
   if (other.rule_count_ > 0) {
-    id_rules_.AddFilteredRulesFromOtherSet(other.id_rules_, only_include,
-                                           other.bloom_hash_backing_,
-                                           bloom_hash_backing_);
+    id_rules_.AddFilteredRulesFromOtherSet(other.id_rules_, only_include, other,
+                                           *this);
     class_rules_.AddFilteredRulesFromOtherSet(other.class_rules_, only_include,
-                                              other.bloom_hash_backing_,
-                                              bloom_hash_backing_);
+                                              other, *this);
     attr_rules_.AddFilteredRulesFromOtherSet(other.attr_rules_, only_include,
-                                             other.bloom_hash_backing_,
-                                             bloom_hash_backing_);
+                                             other, *this);
     // NOTE: attr_substring_matchers_ will be rebuilt in CompactRules().
     tag_rules_.AddFilteredRulesFromOtherSet(other.tag_rules_, only_include,
-                                            other.bloom_hash_backing_,
-                                            bloom_hash_backing_);
+                                            other, *this);
     ua_shadow_pseudo_element_rules_.AddFilteredRulesFromOtherSet(
-        other.ua_shadow_pseudo_element_rules_, only_include,
-        other.bloom_hash_backing_, bloom_hash_backing_);
+        other.ua_shadow_pseudo_element_rules_, only_include, other, *this);
     AddFilteredRulesFromOtherBucket(other, other.link_pseudo_class_rules_,
                                     only_include, &link_pseudo_class_rules_);
     AddFilteredRulesFromOtherBucket(other, other.cue_pseudo_rules_,
@@ -1080,19 +1108,20 @@
 void RuleMap::AddFilteredRulesFromOtherSet(
     const RuleMap& other,
     const HeapHashSet<Member<StyleRule>>& only_include,
-    const Vector<unsigned>& old_bloom_hash_backing,
-    Vector<unsigned>& new_bloom_hash_backing) {
+    const RuleSet& old_rule_set,
+    RuleSet& new_rule_set) {
   if (compacted) {
     Uncompact();
   }
   if (other.compacted) {
     for (const auto& [key, extent] : other.buckets) {
+      Seeker<StyleScope> scope_seeker(old_rule_set.scope_intervals_);
       for (const RuleData& rule_data : other.GetRulesFromExtent(extent)) {
         if (IncludeRule(rule_data.Rule(), only_include)) {
-          RuleData rule_data_copy = rule_data;
-          rule_data_copy.MovedToDifferentRuleSet(old_bloom_hash_backing,
-                                                 new_bloom_hash_backing);
-          Add(key, rule_data_copy);
+          Add(key, rule_data);
+          new_rule_set.NewlyAddedFromDifferentRuleSet(
+              rule_data, scope_seeker.Seek(rule_data.GetPosition()),
+              old_rule_set, backing.back());
         }
       }
     }
@@ -1106,14 +1135,15 @@
 
     // Now that we have the mapping, we can just copy over all the relevant
     // RuleDatas.
+    Seeker<StyleScope> scope_seeker(old_rule_set.scope_intervals_);
     for (wtf_size_t i = 0; i < other.backing.size(); ++i) {
       const unsigned bucket_number = other.bucket_number_[i];
       const RuleData& rule_data = other.backing[i];
       if (IncludeRule(rule_data.Rule(), only_include)) {
-        RuleData rule_data_copy = rule_data;
-        rule_data_copy.MovedToDifferentRuleSet(old_bloom_hash_backing,
-                                               new_bloom_hash_backing);
-        Add(*keys[bucket_number], rule_data_copy);
+        Add(*keys[bucket_number], rule_data);
+        new_rule_set.NewlyAddedFromDifferentRuleSet(
+            rule_data, scope_seeker.Seek(rule_data.GetPosition()), old_rule_set,
+            backing.back());
       }
     }
   }
diff --git a/third_party/blink/renderer/core/css/rule_set.h b/third_party/blink/renderer/core/css/rule_set.h
index 3234db5b..07ce1d48 100644
--- a/third_party/blink/renderer/core/css/rule_set.h
+++ b/third_party/blink/renderer/core/css/rule_set.h
@@ -48,6 +48,8 @@
 
 namespace blink {
 
+class RuleSet;
+
 using AddRuleFlags = unsigned;
 
 enum AddRuleFlag {
@@ -108,7 +110,8 @@
   // give to the constructor), you will need to call
   // MovedToDifferentRuleSet() below. Otherwise,
   // DescendantSelectorIdentifierHashes() will return a slice
-  // into a nonexistent backing.
+  // into a nonexistent backing (and GetPosition() will return
+  // a bogus value, which cannot be used for Seeker lookups).
   RuleData(StyleRule*,
            unsigned selector_index,
            unsigned position,
@@ -153,7 +156,8 @@
   void ComputeBloomFilterHashes(const StyleScope* style_scope,
                                 Vector<unsigned>& backing);
   void MovedToDifferentRuleSet(const Vector<unsigned>& old_backing,
-                               Vector<unsigned>& new_backing);
+                               Vector<unsigned>& new_backing,
+                               unsigned new_position);
 
   void Trace(Visitor*) const;
 
@@ -250,8 +254,8 @@
   void AddFilteredRulesFromOtherSet(
       const RuleMap& other,
       const HeapHashSet<Member<StyleRule>>& only_include,
-      const Vector<unsigned>& old_bloom_hash_backing,
-      Vector<unsigned>& new_bloom_hash_backing);
+      const RuleSet& old_rule_set,
+      RuleSet& new_rule_set);
   base::span<const RuleData> Find(const AtomicString& key) const {
     if (buckets.IsNull()) {
       return {};
@@ -572,6 +576,8 @@
   FRIEND_TEST_ALL_PREFIXES(RuleSetTest, RuleCountNotIncreasedByInvalidRuleData);
   FRIEND_TEST_ALL_PREFIXES(RuleSetTest, RuleDataPositionLimit);
   friend class RuleSetCascadeLayerTest;
+  friend class RuleMap;  // For scope_intervals_ and
+                         // NewlyAddedFromDifferentRuleSet().
 
   using SubstringMatcherMap =
       HashMap<AtomicString, std::unique_ptr<base::SubstringSetMatcher>>;
@@ -614,6 +620,19 @@
                const CascadeLayer*,
                const StyleScope*);
 
+  // Must be called when a RuleData has been added to this RuleSet
+  // through some form that does not go through AddRule();
+  // used during creation of diff rulesets (AddFilteredRulesFromOtherSet()).
+  // In particular, it will adjust the position of new_rule_data,
+  // add it to the necessary intervals for diff rulesets, and adjust
+  // rule_count_.
+  //
+  // Used only by RuleSet itself, and RuleMap (through a friend declaration).
+  void NewlyAddedFromDifferentRuleSet(const RuleData& old_rule_data,
+                                      const StyleScope* style_scope,
+                                      const RuleSet& old_rule_set,
+                                      RuleData& new_rule_data);
+
   void SortKeyframesRulesIfNeeded();
 
   void CompactRules();
diff --git a/third_party/blink/renderer/core/css/rule_set_diff.cc b/third_party/blink/renderer/core/css/rule_set_diff.cc
index d108d16..e0c4246 100644
--- a/third_party/blink/renderer/core/css/rule_set_diff.cc
+++ b/third_party/blink/renderer/core/css/rule_set_diff.cc
@@ -29,6 +29,11 @@
     return nullptr;
   }
 
+  if (old_ruleset_->RuleCount() + new_ruleset_->RuleCount() >=
+      (1 << RuleData::kPositionBits)) {
+    return nullptr;
+  }
+
   RuleSet* ruleset = MakeGarbageCollected<RuleSet>();
   ruleset->AddFilteredRulesFromOtherSet(*old_ruleset_, changed_rules_);
   ruleset->AddFilteredRulesFromOtherSet(*new_ruleset_, changed_rules_);
diff --git a/third_party/blink/renderer/core/css/seeker.h b/third_party/blink/renderer/core/css/seeker.h
new file mode 100644
index 0000000..bc21dce
--- /dev/null
+++ b/third_party/blink/renderer/core/css/seeker.h
@@ -0,0 +1,48 @@
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_SEEKER_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_SEEKER_H_
+
+#include <iterator>
+#include "base/memory/stack_allocated.h"
+#include "third_party/blink/renderer/core/css/rule_set.h"
+
+namespace blink {
+
+// Sequentially scans a sorted list of RuleSet::Interval<T> and seeks
+// for the value for a rule (given by its position). Seek() must be called
+// with non-decreasing rule positions, so that we only need to go
+// through the layer list at most once for all Seek() calls.
+template <class T>
+class Seeker {
+  STACK_ALLOCATED();
+
+ public:
+  explicit Seeker(const HeapVector<RuleSet::Interval<T>>& intervals)
+      : intervals_(intervals), iter_(intervals_.begin()) {}
+
+  const T* Seek(unsigned rule_position) {
+#if DCHECK_IS_ON()
+    DCHECK_GE(rule_position, last_rule_position_);
+    last_rule_position_ = rule_position;
+#endif
+
+    while (iter_ != intervals_.end() &&
+           iter_->start_position <= rule_position) {
+      ++iter_;
+    }
+    if (iter_ == intervals_.begin()) {
+      return nullptr;
+    }
+    return std::prev(iter_)->value.Get();
+  }
+
+ private:
+  const HeapVector<RuleSet::Interval<T>>& intervals_;
+  const RuleSet::Interval<T>* iter_;
+#if DCHECK_IS_ON()
+  unsigned last_rule_position_ = 0;
+#endif
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_SEEKER_H_
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc
index a16c560..f198b0b 100644
--- a/third_party/blink/renderer/core/css/style_engine_test.cc
+++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/css/style_engine.h"
 
+#include <algorithm>
 #include <limits>
 #include <memory>
 
@@ -6962,4 +6963,48 @@
   EXPECT_TRUE(IsUseCounted(WebFeature::kCSSDeclarationAfterNestedRule));
 }
 
+TEST_F(StyleEngineTest, EnsureAppRegionTriggersRelayout) {
+  GetDocument().body()->setInnerHTML(R"HTML(
+    <head>
+    <style>
+      .drag {
+        app-region: drag
+      }
+      .no-drag {
+        app-region: no-drag
+      }
+    </style>
+    </head>
+    <body>
+       <div id="drag-region"></div>
+    </body>
+  )HTML");
+
+  Element* drag_element =
+      GetDocument().getElementById(AtomicString("drag-region"));
+
+  auto regions = GetDocument().AnnotatedRegions();
+  auto* it =
+      std::find_if(regions.begin(), regions.end(),
+                   [](blink::AnnotatedRegionValue s) { return s.draggable; });
+  EXPECT_EQ(it, regions.end()) << "There should be no drag regions";
+
+  drag_element->classList().Add(AtomicString("drag"));
+  UpdateAllLifecyclePhases();
+
+  regions = GetDocument().AnnotatedRegions();
+  it = std::find_if(regions.begin(), regions.end(),
+                    [](blink::AnnotatedRegionValue s) { return s.draggable; });
+  EXPECT_NE(it, regions.end()) << "There should be one drag region";
+
+  drag_element->classList().Add(AtomicString("no-drag"));
+  UpdateAllLifecyclePhases();
+
+  regions = GetDocument().AnnotatedRegions();
+  it = std::find_if(regions.begin(), regions.end(),
+                    [](blink::AnnotatedRegionValue s) { return s.draggable; });
+
+  EXPECT_EQ(it, regions.end()) << "There should be no drag regions";
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 121322bd..c831a0e6 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -9142,6 +9142,18 @@
   post_prerendering_activation_callbacks_.clear();
 }
 
+void Document::AddLCPPredictedCallback(LCPCallback callback) {
+  lcp_predicted_callbacks_.push_back(std::move(callback));
+}
+
+void Document::RunLCPPredictedCallbacks(const Element& lcp_element) {
+  Vector<LCPCallback> callbacks;
+  callbacks.swap(lcp_predicted_callbacks_);
+  for (auto& callback : callbacks) {
+    std::move(callback).Run(lcp_element);
+  }
+}
+
 bool Document::InStyleRecalc() const {
   return lifecycle_.GetState() == DocumentLifecycle::kInStyleRecalc ||
          style_engine_->InContainerQueryStyleRecalc() ||
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
index 1f1c4727..fd9df47 100644
--- a/third_party/blink/renderer/core/dom/document.h
+++ b/third_party/blink/renderer/core/dom/document.h
@@ -1923,6 +1923,10 @@
 
   void AddPostPrerenderingActivationStep(base::OnceClosure callback);
 
+  using LCPCallback = base::OnceCallback<void(const Element&)>;
+  void AddLCPPredictedCallback(LCPCallback callback);
+  void RunLCPPredictedCallbacks(const Element& lcp_element);
+
   class CORE_EXPORT PaintPreviewScope {
     STACK_ALLOCATED();
 
@@ -2241,6 +2245,10 @@
   // https://wicg.github.io/nav-speculation/prerendering.html#document-post-prerendering-activation-steps-list
   Vector<base::OnceClosure> post_prerendering_activation_callbacks_;
 
+  // Callbacks are called when predicted LCP is painted. Never called if
+  // prediction is incorrect.
+  Vector<LCPCallback> lcp_predicted_callbacks_;
+
   bool evaluate_media_queries_on_style_recalc_;
 
   // If we do ignore the pending stylesheet count, then we need to add a boolean
diff --git a/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl.cc b/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl.cc
index b819ba3e..8af443e9 100644
--- a/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl.cc
+++ b/third_party/blink/renderer/core/editing/markers/composition_marker_list_impl.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/editing/markers/composition_marker_list_impl.h"
 
+#include "third_party/blink/renderer/core/editing/markers/sorted_document_marker_list_editor.h"
 #include "third_party/blink/renderer/core/editing/markers/unsorted_document_marker_list_editor.h"
 
 namespace blink {
@@ -18,7 +19,7 @@
 
 void CompositionMarkerListImpl::Add(DocumentMarker* marker) {
   DCHECK_EQ(DocumentMarker::kComposition, marker->GetType());
-  markers_.push_back(marker);
+  UnsortedDocumentMarkerListEditor::AddMarker(&markers_, marker);
 }
 
 void CompositionMarkerListImpl::Clear() {
@@ -33,7 +34,7 @@
 DocumentMarker* CompositionMarkerListImpl::FirstMarkerIntersectingRange(
     unsigned start_offset,
     unsigned end_offset) const {
-  return UnsortedDocumentMarkerListEditor::FirstMarkerIntersectingRange(
+  return SortedDocumentMarkerListEditor::FirstMarkerIntersectingRange(
       markers_, start_offset, end_offset);
 }
 
@@ -60,8 +61,8 @@
                                              unsigned offset,
                                              unsigned old_length,
                                              unsigned new_length) {
-  return UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(
-      &markers_, offset, old_length, new_length);
+  return UnsortedDocumentMarkerListEditor::ShiftMarkers(&markers_, offset,
+                                                        old_length, new_length);
 }
 
 void CompositionMarkerListImpl::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/core/editing/markers/highlight_pseudo_marker_list_impl.cc b/third_party/blink/renderer/core/editing/markers/highlight_pseudo_marker_list_impl.cc
index 17af9128..a162e40 100644
--- a/third_party/blink/renderer/core/editing/markers/highlight_pseudo_marker_list_impl.cc
+++ b/third_party/blink/renderer/core/editing/markers/highlight_pseudo_marker_list_impl.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/editing/markers/highlight_pseudo_marker_list_impl.h"
 
+#include "third_party/blink/renderer/core/editing/markers/sorted_document_marker_list_editor.h"
 #include "third_party/blink/renderer/core/editing/markers/unsorted_document_marker_list_editor.h"
 
 namespace blink {
@@ -15,7 +16,7 @@
 void HighlightPseudoMarkerListImpl::Add(DocumentMarker* marker) {
   DCHECK(marker->GetType() == DocumentMarker::kCustomHighlight ||
          marker->GetType() == DocumentMarker::kTextFragment);
-  markers_.push_back(marker);
+  UnsortedDocumentMarkerListEditor::AddMarker(&markers_, marker);
 }
 
 void HighlightPseudoMarkerListImpl::Clear() {
@@ -30,7 +31,7 @@
 DocumentMarker* HighlightPseudoMarkerListImpl::FirstMarkerIntersectingRange(
     unsigned start_offset,
     unsigned end_offset) const {
-  return UnsortedDocumentMarkerListEditor::FirstMarkerIntersectingRange(
+  return SortedDocumentMarkerListEditor::FirstMarkerIntersectingRange(
       markers_, start_offset, end_offset);
 }
 
@@ -59,8 +60,8 @@
                                                  unsigned offset,
                                                  unsigned old_length,
                                                  unsigned new_length) {
-  return UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(
-      &markers_, offset, old_length, new_length);
+  return UnsortedDocumentMarkerListEditor::ShiftMarkers(&markers_, offset,
+                                                        old_length, new_length);
 }
 
 void HighlightPseudoMarkerListImpl::Trace(blink::Visitor* visitor) const {
diff --git a/third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl.cc b/third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl.cc
index d8084e05..386f25e0 100644
--- a/third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl.cc
+++ b/third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/core/editing/markers/suggestion_marker_list_impl.h"
 
+#include "third_party/blink/renderer/core/editing/markers/sorted_document_marker_list_editor.h"
 #include "third_party/blink/renderer/core/editing/markers/suggestion_marker_replacement_scope.h"
 #include "third_party/blink/renderer/core/editing/markers/unsorted_document_marker_list_editor.h"
 #include "third_party/blink/renderer/platform/wtf/text/unicode.h"
@@ -64,7 +65,7 @@
 
 void SuggestionMarkerListImpl::Add(DocumentMarker* marker) {
   DCHECK_EQ(DocumentMarker::kSuggestion, marker->GetType());
-  markers_.push_back(marker);
+  UnsortedDocumentMarkerListEditor::AddMarker(&markers_, marker);
 }
 
 void SuggestionMarkerListImpl::Clear() {
@@ -79,7 +80,7 @@
 DocumentMarker* SuggestionMarkerListImpl::FirstMarkerIntersectingRange(
     unsigned start_offset,
     unsigned end_offset) const {
-  return UnsortedDocumentMarkerListEditor::FirstMarkerIntersectingRange(
+  return SortedDocumentMarkerListEditor::FirstMarkerIntersectingRange(
       markers_, start_offset, end_offset);
 }
 
@@ -117,7 +118,7 @@
     unsigned offset,
     unsigned old_length,
     unsigned new_length) {
-  // Since suggestion markers are stored unsorted, the quickest way to perform
+  // Since suggestion markers may overlap, the quickest way to perform
   // this operation is to build a new list with the markers not removed by the
   // shift.
   bool did_shift_marker = false;
@@ -163,7 +164,7 @@
     unsigned offset,
     unsigned old_length,
     unsigned new_length) {
-  // Since suggestion markers are stored unsorted, the quickest way to perform
+  // Since suggestion markers may overlap, the quickest way to perform
   // this operation is to build a new list with the markers not removed by the
   // shift.
   bool did_shift_marker = false;
diff --git a/third_party/blink/renderer/core/editing/markers/unsorted_document_marker_list_editor.cc b/third_party/blink/renderer/core/editing/markers/unsorted_document_marker_list_editor.cc
index 8e36f52..711e5a7 100644
--- a/third_party/blink/renderer/core/editing/markers/unsorted_document_marker_list_editor.cc
+++ b/third_party/blink/renderer/core/editing/markers/unsorted_document_marker_list_editor.cc
@@ -9,6 +9,23 @@
 
 namespace blink {
 
+void UnsortedDocumentMarkerListEditor::AddMarker(MarkerList* list,
+                                                 DocumentMarker* marker) {
+  if (list->empty() || list->back()->StartOffset() <= marker->StartOffset()) {
+    list->push_back(marker);
+    return;
+  }
+
+  auto* const pos = std::lower_bound(
+      list->begin(), list->end(), marker,
+      [](const Member<DocumentMarker>& marker_in_list,
+         const DocumentMarker* marker_to_insert) {
+        return marker_in_list->StartOffset() <= marker_to_insert->StartOffset();
+      });
+
+  list->insert(base::checked_cast<wtf_size_t>(pos - list->begin()), marker);
+}
+
 bool UnsortedDocumentMarkerListEditor::MoveMarkers(
     MarkerList* src_list,
     int length,
@@ -24,8 +41,7 @@
       continue;
     }
 
-    // If we're splitting a text node in the middle of a suggestion marker,
-    // remove the marker
+    // Remove the marker if it is split by the edit.
     if (marker->EndOffset() > end_offset)
       continue;
 
@@ -40,8 +56,12 @@
 bool UnsortedDocumentMarkerListEditor::RemoveMarkers(MarkerList* list,
                                                      unsigned start_offset,
                                                      int length) {
-  // For an unsorted marker list, the quickest way to perform this operation is
-  // to build a new list with the markers that aren't being removed.
+  // For overlapping markers, even if sorted, the quickest way to perform
+  // this operation is to build a new list with the markers that aren't
+  // being removed. Exploiting the sort is difficult because markers
+  // may be nested. See
+  // UnsortedDocumentMarkerListEditorTest.RemoveMarkersNestedOverlap
+  // for an example.
   const unsigned end_offset = start_offset + length;
   HeapVector<Member<DocumentMarker>> unremoved_markers;
   for (const Member<DocumentMarker>& marker : *list) {
@@ -57,13 +77,14 @@
   return did_remove_marker;
 }
 
-bool UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(
-    MarkerList* list,
-    unsigned offset,
-    unsigned old_length,
-    unsigned new_length) {
-  // For an unsorted marker list, the quickest way to perform this operation is
-  // to build a new list with the markers not removed by the shift.
+bool UnsortedDocumentMarkerListEditor::ShiftMarkers(MarkerList* list,
+                                                    unsigned offset,
+                                                    unsigned old_length,
+                                                    unsigned new_length) {
+  // For an overlapping marker list, the quickest way to perform this operation
+  // is to build a new list with the markers not removed by the shift. Note that
+  // ComputeOffsetsAfterShift will move markers in such a way that they remain
+  // sorted in StartOffset through this operation.
   bool did_shift_marker = false;
   HeapVector<Member<DocumentMarker>> unremoved_markers;
   for (const Member<DocumentMarker>& marker : *list) {
@@ -88,23 +109,6 @@
   return did_shift_marker;
 }
 
-DocumentMarker* UnsortedDocumentMarkerListEditor::FirstMarkerIntersectingRange(
-    const MarkerList& list,
-    unsigned start_offset,
-    unsigned end_offset) {
-  DCHECK_LE(start_offset, end_offset);
-
-  auto* const it = base::ranges::find_if(
-      list, [start_offset, end_offset](const DocumentMarker* marker) {
-        return marker->StartOffset() < end_offset &&
-               marker->EndOffset() > start_offset;
-      });
-
-  if (it == list.end())
-    return nullptr;
-  return it->Get();
-}
-
 HeapVector<Member<DocumentMarker>>
 UnsortedDocumentMarkerListEditor::MarkersIntersectingRange(
     const MarkerList& list,
@@ -112,9 +116,18 @@
     unsigned end_offset) {
   DCHECK_LE(start_offset, end_offset);
 
+  // Optimize finding the last possible overlapping marker, then iterate
+  // only to there. We can't do better because overlaps may be nested, and
+  // sorted on start does not imply sorted on end.
+  auto* const end_it =
+      std::upper_bound(list.begin(), list.end(), end_offset,
+                       [](unsigned end_offset, const DocumentMarker* marker) {
+                         return end_offset <= marker->StartOffset();
+                       });
+
   HeapVector<Member<DocumentMarker>> results;
   base::ranges::copy_if(
-      list, std::back_inserter(results),
+      list.begin(), end_it, std::back_inserter(results),
       [start_offset, end_offset](const DocumentMarker* marker) {
         return marker->StartOffset() < end_offset &&
                marker->EndOffset() > start_offset;
diff --git a/third_party/blink/renderer/core/editing/markers/unsorted_document_marker_list_editor.h b/third_party/blink/renderer/core/editing/markers/unsorted_document_marker_list_editor.h
index c5059a6..79a53733 100644
--- a/third_party/blink/renderer/core/editing/markers/unsorted_document_marker_list_editor.h
+++ b/third_party/blink/renderer/core/editing/markers/unsorted_document_marker_list_editor.h
@@ -14,11 +14,16 @@
 class DocumentMarker;
 
 // This class holds static utility methods to be used in DocumentMarkerList
-// implementations that store potentially overlapping markers in unsorted order.
+// implementations that store potentially overlapping markers sorted by
+// StartOffset. The sort order for markers with the same StartOffset is
+// undefined. It will initially match the order in which markers are
+// added, but calling ShiftMarkers may change that.
 class CORE_EXPORT UnsortedDocumentMarkerListEditor final {
  public:
   using MarkerList = HeapVector<Member<DocumentMarker>>;
 
+  static void AddMarker(MarkerList*, DocumentMarker*);
+
   // Returns true if a marker was moved, false otherwise.
   static bool MoveMarkers(MarkerList* src_list,
                           int length,
@@ -31,20 +36,10 @@
   // If the text marked by a marker is changed by the edit, this method attempts
   // to keep the marker tracking the marked region rather than removing the
   // marker.
-  static bool ShiftMarkersContentIndependent(MarkerList*,
-                                             unsigned offset,
-                                             unsigned old_length,
-                                             unsigned new_length);
-
-  // Returns the first marker in the specified MarkerList whose interior
-  // overlaps overlap with the range [start_offset, end_offset], or null if
-  // there is no such marker.
-  // Note: since the markers aren't stored in order in an unsorted marker list,
-  // the first marker found isn't necessarily going to be the first marker
-  // ordered by start or end offset.
-  static DocumentMarker* FirstMarkerIntersectingRange(const MarkerList&,
-                                                      unsigned start_offset,
-                                                      unsigned end_offset);
+  static bool ShiftMarkers(MarkerList*,
+                           unsigned offset,
+                           unsigned old_length,
+                           unsigned new_length);
 
   // Returns all markers in the specified MarkerList whose interior overlaps
   // with the range [start_offset, end_offset].
diff --git a/third_party/blink/renderer/core/editing/markers/unsorted_document_marker_list_editor_test.cc b/third_party/blink/renderer/core/editing/markers/unsorted_document_marker_list_editor_test.cc
index ac890c87..c4eb0ba 100644
--- a/third_party/blink/renderer/core/editing/markers/unsorted_document_marker_list_editor_test.cc
+++ b/third_party/blink/renderer/core/editing/markers/unsorted_document_marker_list_editor_test.cc
@@ -28,18 +28,66 @@
   Persistent<HeapVector<Member<DocumentMarker>>> marker_list_;
 };
 
+TEST_F(UnsortedDocumentMarkerListEditorTest, AddMarkersOverlapping) {
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(40, 60));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(0, 30));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(70, 100));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(0, 20));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(0, 40));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(45, 70));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(35, 65));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(90, 100));
+
+  EXPECT_EQ(8u, marker_list_->size());
+  EXPECT_EQ(0u, marker_list_->at(0)->StartOffset());
+  EXPECT_EQ(30u, marker_list_->at(0)->EndOffset());
+  EXPECT_EQ(0u, marker_list_->at(1)->StartOffset());
+  EXPECT_EQ(20u, marker_list_->at(1)->EndOffset());
+  EXPECT_EQ(0u, marker_list_->at(2)->StartOffset());
+  EXPECT_EQ(40u, marker_list_->at(2)->EndOffset());
+  EXPECT_EQ(35u, marker_list_->at(3)->StartOffset());
+  EXPECT_EQ(65u, marker_list_->at(3)->EndOffset());
+  EXPECT_EQ(40u, marker_list_->at(4)->StartOffset());
+  EXPECT_EQ(60u, marker_list_->at(4)->EndOffset());
+  EXPECT_EQ(45u, marker_list_->at(5)->StartOffset());
+  EXPECT_EQ(70u, marker_list_->at(5)->EndOffset());
+  EXPECT_EQ(70u, marker_list_->at(6)->StartOffset());
+  EXPECT_EQ(100u, marker_list_->at(6)->EndOffset());
+  EXPECT_EQ(90u, marker_list_->at(7)->StartOffset());
+  EXPECT_EQ(100u, marker_list_->at(7)->EndOffset());
+}
+
 TEST_F(UnsortedDocumentMarkerListEditorTest, MoveMarkers) {
-  marker_list_->push_back(CreateMarker(30, 40));
-  marker_list_->push_back(CreateMarker(0, 30));
-  marker_list_->push_back(CreateMarker(10, 40));
-  marker_list_->push_back(CreateMarker(0, 20));
-  marker_list_->push_back(CreateMarker(0, 40));
-  marker_list_->push_back(CreateMarker(20, 40));
-  marker_list_->push_back(CreateMarker(20, 30));
-  marker_list_->push_back(CreateMarker(0, 10));
-  marker_list_->push_back(CreateMarker(10, 30));
-  marker_list_->push_back(CreateMarker(10, 20));
-  marker_list_->push_back(CreateMarker(11, 21));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(30, 40));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(0, 30));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(10, 40));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(0, 20));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(0, 40));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(20, 40));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(20, 30));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(0, 10));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(10, 30));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(10, 20));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(11, 21));
 
   DocumentMarkerList* dst_list =
       MakeGarbageCollected<SuggestionMarkerListImpl>();
@@ -48,24 +96,21 @@
   // Markers that start at 11 or later should not be moved.
   UnsortedDocumentMarkerListEditor::MoveMarkers(marker_list_, 11, dst_list);
 
-  std::sort(marker_list_->begin(), marker_list_->end(), compare_markers);
-
   EXPECT_EQ(4u, marker_list_->size());
 
   EXPECT_EQ(11u, marker_list_->at(0)->StartOffset());
   EXPECT_EQ(21u, marker_list_->at(0)->EndOffset());
 
   EXPECT_EQ(20u, marker_list_->at(1)->StartOffset());
-  EXPECT_EQ(30u, marker_list_->at(1)->EndOffset());
+  EXPECT_EQ(40u, marker_list_->at(1)->EndOffset());
 
   EXPECT_EQ(20u, marker_list_->at(2)->StartOffset());
-  EXPECT_EQ(40u, marker_list_->at(2)->EndOffset());
+  EXPECT_EQ(30u, marker_list_->at(2)->EndOffset());
 
   EXPECT_EQ(30u, marker_list_->at(3)->StartOffset());
   EXPECT_EQ(40u, marker_list_->at(3)->EndOffset());
 
   DocumentMarkerVector dst_list_markers = dst_list->GetMarkers();
-  std::sort(dst_list_markers.begin(), dst_list_markers.end(), compare_markers);
 
   // Markers
   EXPECT_EQ(1u, dst_list_markers.size());
@@ -74,23 +119,47 @@
   EXPECT_EQ(10u, dst_list_markers[0]->EndOffset());
 }
 
-TEST_F(UnsortedDocumentMarkerListEditorTest, RemoveMarkersEmptyList) {
-  EXPECT_FALSE(
-      UnsortedDocumentMarkerListEditor::RemoveMarkers(marker_list_, 0, 10));
-  EXPECT_EQ(0u, marker_list_->size());
-}
-
-TEST_F(UnsortedDocumentMarkerListEditorTest, RemoveMarkersTouchingEndpoints) {
-  marker_list_->push_back(CreateMarker(30, 40));
-  marker_list_->push_back(CreateMarker(40, 50));
-  marker_list_->push_back(CreateMarker(10, 20));
-  marker_list_->push_back(CreateMarker(0, 10));
-  marker_list_->push_back(CreateMarker(20, 30));
+TEST_F(UnsortedDocumentMarkerListEditorTest, RemoveMarkersNestedOverlap) {
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(0, 10));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(10, 30));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(15, 20));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(20, 30));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(30, 40));
 
   EXPECT_TRUE(
       UnsortedDocumentMarkerListEditor::RemoveMarkers(marker_list_, 20, 10));
 
-  std::sort(marker_list_->begin(), marker_list_->end(), compare_markers);
+  EXPECT_EQ(3u, marker_list_->size());
+
+  EXPECT_EQ(0u, marker_list_->at(0)->StartOffset());
+  EXPECT_EQ(10u, marker_list_->at(0)->EndOffset());
+
+  EXPECT_EQ(15u, marker_list_->at(1)->StartOffset());
+  EXPECT_EQ(20u, marker_list_->at(1)->EndOffset());
+
+  EXPECT_EQ(30u, marker_list_->at(2)->StartOffset());
+  EXPECT_EQ(40u, marker_list_->at(2)->EndOffset());
+}
+
+TEST_F(UnsortedDocumentMarkerListEditorTest, RemoveMarkersTouchingEndpoints) {
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(30, 40));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(40, 50));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(10, 20));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(0, 10));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(20, 30));
+
+  EXPECT_TRUE(
+      UnsortedDocumentMarkerListEditor::RemoveMarkers(marker_list_, 20, 10));
 
   EXPECT_EQ(4u, marker_list_->size());
 
@@ -109,17 +178,20 @@
 
 TEST_F(UnsortedDocumentMarkerListEditorTest,
        RemoveMarkersOneCharacterIntoInterior) {
-  marker_list_->push_back(CreateMarker(30, 40));
-  marker_list_->push_back(CreateMarker(40, 50));
-  marker_list_->push_back(CreateMarker(10, 20));
-  marker_list_->push_back(CreateMarker(0, 10));
-  marker_list_->push_back(CreateMarker(20, 30));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(30, 40));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(40, 50));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(10, 20));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(0, 10));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(20, 30));
 
   EXPECT_TRUE(
       UnsortedDocumentMarkerListEditor::RemoveMarkers(marker_list_, 19, 12));
 
-  std::sort(marker_list_->begin(), marker_list_->end(), compare_markers);
-
   EXPECT_EQ(2u, marker_list_->size());
 
   EXPECT_EQ(0u, marker_list_->at(0)->StartOffset());
@@ -130,305 +202,262 @@
 }
 
 TEST_F(UnsortedDocumentMarkerListEditorTest,
-       ContentIndependentMarker_ReplaceStartOfMarker) {
-  UnsortedDocumentMarkerListEditor::MarkerList markers;
-  markers.push_back(CreateMarker(0, 10));
+       ShiftMarkers_ReplaceStartOfMarker) {
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(0, 10));
 
   // Replace with shorter text
-  UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0,
-                                                                   5, 4);
+  UnsortedDocumentMarkerListEditor::ShiftMarkers(marker_list_, 0, 5, 4);
 
-  EXPECT_EQ(1u, markers.size());
-  EXPECT_EQ(0u, markers[0]->StartOffset());
-  EXPECT_EQ(9u, markers[0]->EndOffset());
+  EXPECT_EQ(1u, marker_list_->size());
+  EXPECT_EQ(0u, marker_list_->at(0)->StartOffset());
+  EXPECT_EQ(9u, marker_list_->at(0)->EndOffset());
 
   // Replace with longer text
-  UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0,
-                                                                   4, 5);
+  UnsortedDocumentMarkerListEditor::ShiftMarkers(marker_list_, 0, 4, 5);
 
-  EXPECT_EQ(1u, markers.size());
-  EXPECT_EQ(0u, markers[0]->StartOffset());
-  EXPECT_EQ(10u, markers[0]->EndOffset());
+  EXPECT_EQ(1u, marker_list_->size());
+  EXPECT_EQ(0u, marker_list_->at(0)->StartOffset());
+  EXPECT_EQ(10u, marker_list_->at(0)->EndOffset());
 
   // Replace with text of same length
-  UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0,
-                                                                   5, 5);
+  UnsortedDocumentMarkerListEditor::ShiftMarkers(marker_list_, 0, 5, 5);
 
-  EXPECT_EQ(1u, markers.size());
-  EXPECT_EQ(0u, markers[0]->StartOffset());
-  EXPECT_EQ(10u, markers[0]->EndOffset());
+  EXPECT_EQ(1u, marker_list_->size());
+  EXPECT_EQ(0u, marker_list_->at(0)->StartOffset());
+  EXPECT_EQ(10u, marker_list_->at(0)->EndOffset());
 }
 
 TEST_F(UnsortedDocumentMarkerListEditorTest,
-       ContentIndependentMarker_ReplaceContainsStartOfMarker) {
-  UnsortedDocumentMarkerListEditor::MarkerList markers;
-  markers.push_back(CreateMarker(5, 15));
+       ShiftMarkers_ReplaceContainsStartOfMarker) {
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(5, 15));
 
-  UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0,
-                                                                   10, 10);
+  UnsortedDocumentMarkerListEditor::ShiftMarkers(marker_list_, 0, 10, 10);
 
-  EXPECT_EQ(1u, markers.size());
-  EXPECT_EQ(10u, markers[0]->StartOffset());
-  EXPECT_EQ(15u, markers[0]->EndOffset());
+  EXPECT_EQ(1u, marker_list_->size());
+  EXPECT_EQ(10u, marker_list_->at(0)->StartOffset());
+  EXPECT_EQ(15u, marker_list_->at(0)->EndOffset());
 }
 
-TEST_F(UnsortedDocumentMarkerListEditorTest,
-       ContentIndependentMarker_ReplaceEndOfMarker) {
-  UnsortedDocumentMarkerListEditor::MarkerList markers;
-  markers.push_back(CreateMarker(0, 10));
+TEST_F(UnsortedDocumentMarkerListEditorTest, ShiftMarkers_ReplaceEndOfMarker) {
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(0, 10));
 
   // Replace with shorter text
-  UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 5,
-                                                                   5, 4);
+  UnsortedDocumentMarkerListEditor::ShiftMarkers(marker_list_, 5, 5, 4);
 
-  EXPECT_EQ(1u, markers.size());
-  EXPECT_EQ(0u, markers[0]->StartOffset());
-  EXPECT_EQ(9u, markers[0]->EndOffset());
+  EXPECT_EQ(1u, marker_list_->size());
+  EXPECT_EQ(0u, marker_list_->at(0)->StartOffset());
+  EXPECT_EQ(9u, marker_list_->at(0)->EndOffset());
 
   // Replace with longer text
-  UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 5,
-                                                                   4, 5);
+  UnsortedDocumentMarkerListEditor::ShiftMarkers(marker_list_, 5, 4, 5);
 
-  EXPECT_EQ(1u, markers.size());
-  EXPECT_EQ(0u, markers[0]->StartOffset());
-  EXPECT_EQ(10u, markers[0]->EndOffset());
+  EXPECT_EQ(1u, marker_list_->size());
+  EXPECT_EQ(0u, marker_list_->at(0)->StartOffset());
+  EXPECT_EQ(10u, marker_list_->at(0)->EndOffset());
 
   // Replace with text of same length
-  UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 5,
-                                                                   5, 5);
+  UnsortedDocumentMarkerListEditor::ShiftMarkers(marker_list_, 5, 5, 5);
 
-  EXPECT_EQ(1u, markers.size());
-  EXPECT_EQ(0u, markers[0]->StartOffset());
-  EXPECT_EQ(10u, markers[0]->EndOffset());
+  EXPECT_EQ(1u, marker_list_->size());
+  EXPECT_EQ(0u, marker_list_->at(0)->StartOffset());
+  EXPECT_EQ(10u, marker_list_->at(0)->EndOffset());
 }
 
 TEST_F(UnsortedDocumentMarkerListEditorTest,
-       ContentIndependentMarker_ReplaceContainsEndOfMarker) {
-  UnsortedDocumentMarkerListEditor::MarkerList markers;
-  markers.push_back(CreateMarker(0, 10));
+       ShiftMarkers_ReplaceContainsEndOfMarker) {
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(0, 10));
 
-  UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 5,
-                                                                   10, 10);
+  UnsortedDocumentMarkerListEditor::ShiftMarkers(marker_list_, 5, 10, 10);
 
-  EXPECT_EQ(1u, markers.size());
-  EXPECT_EQ(0u, markers[0]->StartOffset());
-  EXPECT_EQ(5u, markers[0]->EndOffset());
+  EXPECT_EQ(1u, marker_list_->size());
+  EXPECT_EQ(0u, marker_list_->at(0)->StartOffset());
+  EXPECT_EQ(5u, marker_list_->at(0)->EndOffset());
 }
 
-TEST_F(UnsortedDocumentMarkerListEditorTest,
-       ContentIndependentMarker_ReplaceEntireMarker) {
-  UnsortedDocumentMarkerListEditor::MarkerList markers;
-  markers.push_back(CreateMarker(0, 10));
+TEST_F(UnsortedDocumentMarkerListEditorTest, ShiftMarkers_ReplaceEntireMarker) {
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(0, 10));
 
   // Replace with shorter text
-  UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0,
-                                                                   10, 9);
+  UnsortedDocumentMarkerListEditor::ShiftMarkers(marker_list_, 0, 10, 9);
 
-  EXPECT_EQ(1u, markers.size());
-  EXPECT_EQ(0u, markers[0]->StartOffset());
-  EXPECT_EQ(9u, markers[0]->EndOffset());
+  EXPECT_EQ(1u, marker_list_->size());
+  EXPECT_EQ(0u, marker_list_->at(0)->StartOffset());
+  EXPECT_EQ(9u, marker_list_->at(0)->EndOffset());
 
   // Replace with longer text
-  UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0,
-                                                                   9, 10);
+  UnsortedDocumentMarkerListEditor::ShiftMarkers(marker_list_, 0, 9, 10);
 
-  EXPECT_EQ(1u, markers.size());
-  EXPECT_EQ(0u, markers[0]->StartOffset());
-  EXPECT_EQ(10u, markers[0]->EndOffset());
+  EXPECT_EQ(1u, marker_list_->size());
+  EXPECT_EQ(0u, marker_list_->at(0)->StartOffset());
+  EXPECT_EQ(10u, marker_list_->at(0)->EndOffset());
 
   // Replace with text of same length
-  UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0,
-                                                                   10, 10);
+  UnsortedDocumentMarkerListEditor::ShiftMarkers(marker_list_, 0, 10, 10);
 
-  EXPECT_EQ(1u, markers.size());
-  EXPECT_EQ(0u, markers[0]->StartOffset());
-  EXPECT_EQ(10u, markers[0]->EndOffset());
+  EXPECT_EQ(1u, marker_list_->size());
+  EXPECT_EQ(0u, marker_list_->at(0)->StartOffset());
+  EXPECT_EQ(10u, marker_list_->at(0)->EndOffset());
 }
 
 TEST_F(UnsortedDocumentMarkerListEditorTest,
-       ContentIndependentMarker_ReplaceTextWithMarkerAtBeginning) {
-  UnsortedDocumentMarkerListEditor::MarkerList markers;
-  markers.push_back(CreateMarker(0, 10));
+       ShiftMarkers_ReplaceTextWithMarkerAtBeginning) {
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(0, 10));
 
-  UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0,
-                                                                   15, 15);
+  UnsortedDocumentMarkerListEditor::ShiftMarkers(marker_list_, 0, 15, 15);
 
-  EXPECT_EQ(0u, markers.size());
+  EXPECT_EQ(0u, marker_list_->size());
 }
 
 TEST_F(UnsortedDocumentMarkerListEditorTest,
-       ContentIndependentMarker_ReplaceTextWithMarkerAtEnd) {
-  UnsortedDocumentMarkerListEditor::MarkerList markers;
-  markers.push_back(CreateMarker(5, 15));
+       ShiftMarkers_ReplaceTextWithMarkerAtEnd) {
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(5, 15));
 
-  UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0,
-                                                                   15, 15);
+  UnsortedDocumentMarkerListEditor::ShiftMarkers(marker_list_, 0, 15, 15);
 
-  EXPECT_EQ(0u, markers.size());
+  EXPECT_EQ(0u, marker_list_->size());
 }
 
-TEST_F(UnsortedDocumentMarkerListEditorTest,
-       ContentIndependentMarker_Deletions) {
-  UnsortedDocumentMarkerListEditor::MarkerList markers;
-  markers.push_back(CreateMarker(0, 5));
-  markers.push_back(CreateMarker(5, 10));
-  markers.push_back(CreateMarker(10, 15));
-  markers.push_back(CreateMarker(15, 20));
-  markers.push_back(CreateMarker(20, 25));
+TEST_F(UnsortedDocumentMarkerListEditorTest, ShiftMarkers_Deletions) {
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_, CreateMarker(0, 5));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(5, 10));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(10, 15));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(15, 20));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(20, 25));
 
   // Delete range containing the end of the second marker, the entire third
   // marker, and the start of the fourth marker
-  UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 8,
-                                                                   9, 0);
+  UnsortedDocumentMarkerListEditor::ShiftMarkers(marker_list_, 8, 9, 0);
 
-  EXPECT_EQ(4u, markers.size());
+  EXPECT_EQ(4u, marker_list_->size());
 
-  EXPECT_EQ(0u, markers[0]->StartOffset());
-  EXPECT_EQ(5u, markers[0]->EndOffset());
+  EXPECT_EQ(0u, marker_list_->at(0)->StartOffset());
+  EXPECT_EQ(5u, marker_list_->at(0)->EndOffset());
 
-  EXPECT_EQ(5u, markers[1]->StartOffset());
-  EXPECT_EQ(8u, markers[1]->EndOffset());
+  EXPECT_EQ(5u, marker_list_->at(1)->StartOffset());
+  EXPECT_EQ(8u, marker_list_->at(1)->EndOffset());
 
-  EXPECT_EQ(8u, markers[2]->StartOffset());
-  EXPECT_EQ(11u, markers[2]->EndOffset());
+  EXPECT_EQ(8u, marker_list_->at(2)->StartOffset());
+  EXPECT_EQ(11u, marker_list_->at(2)->EndOffset());
 
-  EXPECT_EQ(11u, markers[3]->StartOffset());
-  EXPECT_EQ(16u, markers[3]->EndOffset());
+  EXPECT_EQ(11u, marker_list_->at(3)->StartOffset());
+  EXPECT_EQ(16u, marker_list_->at(3)->EndOffset());
 }
 
 TEST_F(UnsortedDocumentMarkerListEditorTest,
-       ContentIndependentMarker_DeleteExactlyOnMarker) {
-  UnsortedDocumentMarkerListEditor::MarkerList markers;
-  markers.push_back(CreateMarker(0, 10));
+       ShiftMarkers_DeletionWithinNested) {
+  // A marker that overlaps the range with markers that do not overlap
+  // nested within it.
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(5, 35));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(7, 10));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(15, 25));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(30, 32));
 
-  UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 0,
-                                                                   10, 0);
+  // Delete range overlapping the outermost marker and containing the
+  // third marker.
+  UnsortedDocumentMarkerListEditor::ShiftMarkers(marker_list_, 15, 10, 0);
 
-  EXPECT_EQ(0u, markers.size());
+  EXPECT_EQ(3u, marker_list_->size());
+
+  EXPECT_EQ(5u, marker_list_->at(0)->StartOffset());
+  EXPECT_EQ(25u, marker_list_->at(0)->EndOffset());
+
+  EXPECT_EQ(7u, marker_list_->at(1)->StartOffset());
+  EXPECT_EQ(10u, marker_list_->at(1)->EndOffset());
+
+  EXPECT_EQ(20u, marker_list_->at(2)->StartOffset());
+  EXPECT_EQ(22u, marker_list_->at(2)->EndOffset());
 }
 
 TEST_F(UnsortedDocumentMarkerListEditorTest,
-       ContentIndependentMarker_InsertInMarkerInterior) {
-  UnsortedDocumentMarkerListEditor::MarkerList markers;
-  markers.push_back(CreateMarker(0, 5));
-  markers.push_back(CreateMarker(5, 10));
-  markers.push_back(CreateMarker(10, 15));
+       ShiftMarkers_DeleteExactlyOnMarker) {
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(0, 10));
+
+  UnsortedDocumentMarkerListEditor::ShiftMarkers(marker_list_, 0, 10, 0);
+
+  EXPECT_EQ(0u, marker_list_->size());
+}
+
+TEST_F(UnsortedDocumentMarkerListEditorTest,
+       ShiftMarkers_InsertInMarkerInterior) {
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_, CreateMarker(0, 5));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(5, 10));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(10, 15));
 
   // insert in middle of second marker
-  UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 7,
-                                                                   0, 5);
+  UnsortedDocumentMarkerListEditor::ShiftMarkers(marker_list_, 7, 0, 5);
 
-  EXPECT_EQ(3u, markers.size());
+  EXPECT_EQ(3u, marker_list_->size());
 
-  EXPECT_EQ(0u, markers[0]->StartOffset());
-  EXPECT_EQ(5u, markers[0]->EndOffset());
+  EXPECT_EQ(0u, marker_list_->at(0)->StartOffset());
+  EXPECT_EQ(5u, marker_list_->at(0)->EndOffset());
 
-  EXPECT_EQ(5u, markers[1]->StartOffset());
-  EXPECT_EQ(15u, markers[1]->EndOffset());
+  EXPECT_EQ(5u, marker_list_->at(1)->StartOffset());
+  EXPECT_EQ(15u, marker_list_->at(1)->EndOffset());
 
-  EXPECT_EQ(15u, markers[2]->StartOffset());
-  EXPECT_EQ(20u, markers[2]->EndOffset());
+  EXPECT_EQ(15u, marker_list_->at(2)->StartOffset());
+  EXPECT_EQ(20u, marker_list_->at(2)->EndOffset());
 }
 
 TEST_F(UnsortedDocumentMarkerListEditorTest,
-       ContentIndependentMarker_InsertBetweenMarkers) {
-  UnsortedDocumentMarkerListEditor::MarkerList markers;
-  markers.push_back(CreateMarker(0, 5));
-  markers.push_back(CreateMarker(5, 10));
-  markers.push_back(CreateMarker(10, 15));
+       ShiftMarkers_InsertBetweenMarkers) {
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_, CreateMarker(0, 5));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(5, 10));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(10, 15));
 
   // insert before second marker
-  UnsortedDocumentMarkerListEditor::ShiftMarkersContentIndependent(&markers, 5,
-                                                                   0, 5);
+  UnsortedDocumentMarkerListEditor::ShiftMarkers(marker_list_, 5, 0, 5);
 
-  EXPECT_EQ(3u, markers.size());
+  EXPECT_EQ(3u, marker_list_->size());
 
-  EXPECT_EQ(0u, markers[0]->StartOffset());
-  EXPECT_EQ(5u, markers[0]->EndOffset());
+  EXPECT_EQ(0u, marker_list_->at(0)->StartOffset());
+  EXPECT_EQ(5u, marker_list_->at(0)->EndOffset());
 
-  EXPECT_EQ(10u, markers[1]->StartOffset());
-  EXPECT_EQ(15u, markers[1]->EndOffset());
+  EXPECT_EQ(10u, marker_list_->at(1)->StartOffset());
+  EXPECT_EQ(15u, marker_list_->at(1)->EndOffset());
 
-  EXPECT_EQ(15u, markers[2]->StartOffset());
-  EXPECT_EQ(20u, markers[2]->EndOffset());
-}
-
-TEST_F(UnsortedDocumentMarkerListEditorTest,
-       FirstMarkerIntersectingRange_Empty) {
-  DocumentMarker* marker =
-      UnsortedDocumentMarkerListEditor::FirstMarkerIntersectingRange(
-          *marker_list_, 0, 10);
-  EXPECT_EQ(nullptr, marker);
-}
-
-TEST_F(UnsortedDocumentMarkerListEditorTest,
-       FirstMarkerIntersectingRange_RangeContainingNoMarkers) {
-  UnsortedDocumentMarkerListEditor::MarkerList markers;
-  markers.push_back(CreateMarker(0, 5));
-  DocumentMarker* marker =
-      UnsortedDocumentMarkerListEditor::FirstMarkerIntersectingRange(markers, 5,
-                                                                     15);
-  EXPECT_EQ(nullptr, marker);
-}
-
-TEST_F(UnsortedDocumentMarkerListEditorTest,
-       FirstMarkerIntersectingRange_TouchingStart) {
-  marker_list_->push_back(CreateMarker(1, 10));
-  marker_list_->push_back(CreateMarker(0, 10));
-
-  DocumentMarker* marker =
-      UnsortedDocumentMarkerListEditor::FirstMarkerIntersectingRange(
-          *marker_list_, 0, 1);
-
-  EXPECT_NE(nullptr, marker);
-  EXPECT_EQ(0u, marker->StartOffset());
-  EXPECT_EQ(10u, marker->EndOffset());
-}
-
-TEST_F(UnsortedDocumentMarkerListEditorTest,
-       FirstMarkerIntersectingRange_TouchingEnd) {
-  marker_list_->push_back(CreateMarker(0, 9));
-  marker_list_->push_back(CreateMarker(0, 10));
-
-  DocumentMarker* marker =
-      UnsortedDocumentMarkerListEditor::FirstMarkerIntersectingRange(
-          *marker_list_, 9, 10);
-
-  EXPECT_NE(nullptr, marker);
-  EXPECT_EQ(0u, marker->StartOffset());
-  EXPECT_EQ(10u, marker->EndOffset());
-}
-
-TEST_F(UnsortedDocumentMarkerListEditorTest,
-       FirstMarkerIntersectingRange_CollapsedRange) {
-  marker_list_->push_back(CreateMarker(5, 10));
-
-  DocumentMarker* marker =
-      UnsortedDocumentMarkerListEditor::FirstMarkerIntersectingRange(
-          *marker_list_, 7, 7);
-
-  EXPECT_NE(nullptr, marker);
-  EXPECT_EQ(5u, marker->StartOffset());
-  EXPECT_EQ(10u, marker->EndOffset());
+  EXPECT_EQ(15u, marker_list_->at(2)->StartOffset());
+  EXPECT_EQ(20u, marker_list_->at(2)->EndOffset());
 }
 
 TEST_F(UnsortedDocumentMarkerListEditorTest,
        MarkersIntersectingRange_RangeContainingNoMarkers) {
-  UnsortedDocumentMarkerListEditor::MarkerList markers;
-  markers.push_back(CreateMarker(0, 10));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(0, 10));
 
   UnsortedDocumentMarkerListEditor::MarkerList markers_intersecting_range =
-      UnsortedDocumentMarkerListEditor::MarkersIntersectingRange(markers, 10,
-                                                                 15);
+      UnsortedDocumentMarkerListEditor::MarkersIntersectingRange(*marker_list_,
+                                                                 10, 15);
   EXPECT_EQ(0u, markers_intersecting_range.size());
 }
 
 TEST_F(UnsortedDocumentMarkerListEditorTest,
        MarkersIntersectingRange_TouchingStart) {
-  marker_list_->push_back(CreateMarker(0, 9));
-  marker_list_->push_back(CreateMarker(1, 9));
-  marker_list_->push_back(CreateMarker(0, 10));
-  marker_list_->push_back(CreateMarker(1, 10));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_, CreateMarker(0, 9));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_, CreateMarker(1, 9));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(0, 10));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(1, 10));
 
   UnsortedDocumentMarkerListEditor::MarkerList markers_intersecting_range =
       UnsortedDocumentMarkerListEditor::MarkersIntersectingRange(*marker_list_,
@@ -445,10 +474,12 @@
 
 TEST_F(UnsortedDocumentMarkerListEditorTest,
        MarkersIntersectingRange_TouchingEnd) {
-  marker_list_->push_back(CreateMarker(0, 9));
-  marker_list_->push_back(CreateMarker(1, 9));
-  marker_list_->push_back(CreateMarker(0, 10));
-  marker_list_->push_back(CreateMarker(1, 10));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_, CreateMarker(0, 9));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_, CreateMarker(1, 9));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(0, 10));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(1, 10));
 
   UnsortedDocumentMarkerListEditor::MarkerList markers_intersecting_range =
       UnsortedDocumentMarkerListEditor::MarkersIntersectingRange(*marker_list_,
@@ -465,15 +496,40 @@
 
 TEST_F(UnsortedDocumentMarkerListEditorTest,
        MarkersIntersectingRange_CollapsedRange) {
-  UnsortedDocumentMarkerListEditor::MarkerList markers;
-  markers.push_back(CreateMarker(5, 10));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(5, 10));
 
   UnsortedDocumentMarkerListEditor::MarkerList markers_intersecting_range =
-      UnsortedDocumentMarkerListEditor::MarkersIntersectingRange(markers, 7, 7);
+      UnsortedDocumentMarkerListEditor::MarkersIntersectingRange(*marker_list_,
+                                                                 7, 7);
   EXPECT_EQ(1u, markers_intersecting_range.size());
 
   EXPECT_EQ(5u, markers_intersecting_range[0]->StartOffset());
   EXPECT_EQ(10u, markers_intersecting_range[0]->EndOffset());
 }
 
+TEST_F(UnsortedDocumentMarkerListEditorTest,
+       MarkersIntersectingRange_NestedMarkers) {
+  // A marker that overlaps the range with markers that do not overlap
+  // nested within it.
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(5, 35));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(7, 10));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(15, 25));
+  UnsortedDocumentMarkerListEditor::AddMarker(marker_list_,
+                                              CreateMarker(30, 32));
+
+  UnsortedDocumentMarkerListEditor::MarkerList markers_intersecting_range =
+      UnsortedDocumentMarkerListEditor::MarkersIntersectingRange(*marker_list_,
+                                                                 15, 25);
+  EXPECT_EQ(2u, markers_intersecting_range.size());
+
+  EXPECT_EQ(5u, markers_intersecting_range[0]->StartOffset());
+  EXPECT_EQ(35u, markers_intersecting_range[0]->EndOffset());
+  EXPECT_EQ(15u, markers_intersecting_range[1]->StartOffset());
+  EXPECT_EQ(25u, markers_intersecting_range[1]->EndOffset());
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/html_element.cc b/third_party/blink/renderer/core/html/html_element.cc
index 73de9e2f..6c2f511 100644
--- a/third_party/blink/renderer/core/html/html_element.cc
+++ b/third_party/blink/renderer/core/html/html_element.cc
@@ -2270,9 +2270,34 @@
 bool HTMLElement::HandleInvokeInternal(HTMLElement& invoker,
                                        AtomicString& action) {
   if (PopoverType() == PopoverValueType::kNone) {
-    return false;
+    if (!(EqualIgnoringASCIICase(action, keywords::kToggleFullscreen) ||
+          EqualIgnoringASCIICase(action, keywords::kRequestFullscreen) ||
+          EqualIgnoringASCIICase(action, keywords::kExitFullscreen))) {
+      return false;
+    }
   }
+
   auto& document = GetDocument();
+
+  if (EqualIgnoringASCIICase(action, keywords::kToggleFullscreen)) {
+    if (Fullscreen::IsFullscreenElement(*this)) {
+      Fullscreen::ExitFullscreen(document);
+    } else {
+      Fullscreen::RequestFullscreen(*this);
+    }
+    return true;
+  } else if (EqualIgnoringASCIICase(action, keywords::kRequestFullscreen)) {
+    if (!Fullscreen::IsFullscreenElement(*this)) {
+      Fullscreen::RequestFullscreen(*this);
+    }
+    return true;
+  } else if (EqualIgnoringASCIICase(action, keywords::kExitFullscreen)) {
+    if (Fullscreen::IsFullscreenElement(*this)) {
+      Fullscreen::ExitFullscreen(document);
+    }
+    return true;
+  }
+
   // Note that the order is: `mousedown` which runs popover light dismiss
   // code, then (for clicked elements) focus is set to the clicked
   // element, then |DOMActivate| runs here. Also note that the light
diff --git a/third_party/blink/renderer/core/html/keywords.json5 b/third_party/blink/renderer/core/html/keywords.json5
index 97b1919..76fa06a 100644
--- a/third_party/blink/renderer/core/html/keywords.json5
+++ b/third_party/blink/renderer/core/html/keywords.json5
@@ -80,6 +80,10 @@
     "open",
     // invokeaction for input and select
     "showPicker",
+    // invokeaction for fullscreen
+    "toggleFullscreen",
+    "requestFullscreen",
+    "exitFullscreen",
 
     // loading attribute
     // https://github.com/scott-little/lazyload#ways-the-loading-attribute-can-be-used
diff --git a/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc b/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc
index 6ed6f6c..e0cff1e 100644
--- a/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_dom_agent.cc
@@ -1184,6 +1184,21 @@
   HeapVector<Member<Document>> docs = Documents();
   HeapLinkedHashSet<Member<Node>> result_collector;
 
+  // Selector evaluation
+  for (Document* document : docs) {
+    DummyExceptionStateForTesting exception_state;
+    StaticElementList* element_list = document->QuerySelectorAll(
+        AtomicString(whitespace_trimmed_query), exception_state);
+    if (exception_state.HadException() || !element_list) {
+      continue;
+    }
+
+    unsigned size = element_list->length();
+    for (unsigned i = 0; i < size; ++i) {
+      result_collector.insert(element_list->item(i));
+    }
+  }
+
   for (Document* document : docs) {
     Node* document_element = document->documentElement();
     Node* node = document_element;
@@ -1266,19 +1281,6 @@
     }
   }
 
-  // Selector evaluation
-  for (Document* document : docs) {
-    DummyExceptionStateForTesting exception_state;
-    StaticElementList* element_list = document->QuerySelectorAll(
-        AtomicString(whitespace_trimmed_query), exception_state);
-    if (exception_state.HadException() || !element_list)
-      continue;
-
-    unsigned size = element_list->length();
-    for (unsigned i = 0; i < size; ++i)
-      result_collector.insert(element_list->item(i));
-  }
-
   *search_id = IdentifiersFactory::CreateIdentifier();
   HeapVector<Member<Node>>* results_it =
       search_results_
diff --git a/third_party/blink/renderer/core/layout/layout_view.cc b/third_party/blink/renderer/core/layout/layout_view.cc
index 4be91c4..b434e7a 100644
--- a/third_party/blink/renderer/core/layout/layout_view.cc
+++ b/third_party/blink/renderer/core/layout/layout_view.cc
@@ -532,6 +532,11 @@
 
       // This adjustment should always be an expansion of the current
       // viewport.
+
+      // TODO(https://crbug.com/1495157): The snapshot size can be smaller (by
+      // one pixel) than the frame on mobile viewport. Investigate why. Consider
+      // adding `<meta name="viewport" content="width=device-width">` to the
+      // HTML if this occurs.
       DCHECK_GE(transition->GetSnapshotRootSize().width(),
                 frame_view_->Size().width());
       DCHECK_GE(transition->GetSnapshotRootSize().height(),
diff --git a/third_party/blink/renderer/core/lcp_critical_path_predictor/element_locator.cc b/third_party/blink/renderer/core/lcp_critical_path_predictor/element_locator.cc
index 39965fc..8944d10 100644
--- a/third_party/blink/renderer/core/lcp_critical_path_predictor/element_locator.cc
+++ b/third_party/blink/renderer/core/lcp_critical_path_predictor/element_locator.cc
@@ -59,7 +59,7 @@
   return locator;
 }
 
-String ToString(const ElementLocator& locator) {
+String ToStringForTesting(const ElementLocator& locator) {
   StringBuilder builder;
 
   for (const auto& c : locator.components()) {
diff --git a/third_party/blink/renderer/core/lcp_critical_path_predictor/element_locator.h b/third_party/blink/renderer/core/lcp_critical_path_predictor/element_locator.h
index 6ae06226..ee8915c 100644
--- a/third_party/blink/renderer/core/lcp_critical_path_predictor/element_locator.h
+++ b/third_party/blink/renderer/core/lcp_critical_path_predictor/element_locator.h
@@ -27,7 +27,7 @@
 // Intended for testing and debugging purposes.
 // Note: Since we are using the MessageLite runtime, TextFormat is not
 //       available, so we need something on our own.
-CORE_EXPORT String ToString(const ElementLocator&);
+CORE_EXPORT String ToStringForTesting(const ElementLocator&);
 
 // An item of `stack of open elements`
 // https://html.spec.whatwg.org/multipage/parsing.html#stack-of-open-elements
diff --git a/third_party/blink/renderer/core/lcp_critical_path_predictor/element_locator_test.cc b/third_party/blink/renderer/core/lcp_critical_path_predictor/element_locator_test.cc
index 8b8dcad..ac71d79 100644
--- a/third_party/blink/renderer/core/lcp_critical_path_predictor/element_locator_test.cc
+++ b/third_party/blink/renderer/core/lcp_critical_path_predictor/element_locator_test.cc
@@ -70,7 +70,7 @@
     auto locator = element_locator::OfElement(*target);
 
     if (test_case.expected_locator_string) {
-      String locator_string = element_locator::ToString(locator);
+      String locator_string = element_locator::ToStringForTesting(locator);
       EXPECT_EQ(String(test_case.expected_locator_string), locator_string);
     }
   }
@@ -177,7 +177,8 @@
   auto* c1 = locator.add_components()->mutable_id();
   c1->set_id_attr("container");
 
-  EXPECT_EQ(String("/p[2]/#container"), element_locator::ToString(locator));
+  EXPECT_EQ(String("/p[2]/#container"),
+            element_locator::ToStringForTesting(locator));
 
   element_locator::TokenStreamMatcher matcher({locator});
   Vector<Expectation> exps = {
@@ -204,7 +205,7 @@
   c2->set_id_attr("container");
 
   EXPECT_EQ(String("/img[1]/article[2]/#container"),
-            element_locator::ToString(locator));
+            element_locator::ToStringForTesting(locator));
 
   element_locator::TokenStreamMatcher matcher({locator});
   Vector<Expectation> exps = {
diff --git a/third_party/blink/renderer/core/lcp_critical_path_predictor/lcp_critical_path_predictor.cc b/third_party/blink/renderer/core/lcp_critical_path_predictor/lcp_critical_path_predictor.cc
index 9a0cd90..18dbccf1 100644
--- a/third_party/blink/renderer/core/lcp_critical_path_predictor/lcp_critical_path_predictor.cc
+++ b/third_party/blink/renderer/core/lcp_critical_path_predictor/lcp_critical_path_predictor.cc
@@ -43,6 +43,10 @@
 void LCPCriticalPathPredictor::set_lcp_element_locators(
     Vector<ElementLocator> locators) {
   lcp_element_locators_ = std::move(locators);
+  if (lcp_element_locators_.size()) {
+    first_lcp_element_locator_string_ =
+        lcp_element_locators_[0].SerializeAsString();
+  }
 }
 
 void LCPCriticalPathPredictor::set_lcp_influencer_scripts(
@@ -65,6 +69,19 @@
   if (base::FeatureList::IsEnabled(features::kLCPCriticalPathPredictor)) {
     std::string lcp_element_locator_string =
         element_locator::OfElement(lcp_element).SerializeAsString();
+
+    bool lcp_timing_was_predicted = false;
+    // Predicted the most frequent LCP would be next LCP and record the
+    // actual result. see PredictLcpElementLocators() for the `hint` contents.
+    // TODO(crbug.com/1493255): We might need another predictor e.g. checking
+    // other element_locators as well.
+    if (first_lcp_element_locator_string_ &&
+        *first_lcp_element_locator_string_ == lcp_element_locator_string) {
+      // TODO(crbug.com/1493255): Trigger callbacks for the entire frame tree.
+      frame_->GetDocument()->RunLCPPredictedCallbacks(lcp_element);
+      lcp_timing_was_predicted = true;
+    }
+
     features::LcppRecordedLcpElementTypes recordable_lcp_element_type =
         features::kLCPCriticalPathPredictorRecordedLcpElementTypes.Get();
     bool should_record_element_locator =
@@ -83,7 +100,8 @@
           base::checked_cast<size_t>(
               features::kLCPCriticalPathPredictorMaxElementLocatorLength
                   .Get())) {
-        GetHost().SetLcpElementLocator(lcp_element_locator_string);
+        GetHost().SetLcpElementLocator(lcp_element_locator_string,
+                                       lcp_timing_was_predicted);
       }
     }
   }
diff --git a/third_party/blink/renderer/core/lcp_critical_path_predictor/lcp_critical_path_predictor.h b/third_party/blink/renderer/core/lcp_critical_path_predictor/lcp_critical_path_predictor.h
index fd9a6a1..5e7efe50 100644
--- a/third_party/blink/renderer/core/lcp_critical_path_predictor/lcp_critical_path_predictor.h
+++ b/third_party/blink/renderer/core/lcp_critical_path_predictor/lcp_critical_path_predictor.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_LCP_CRITICAL_PATH_PREDICTOR_LCP_CRITICAL_PATH_PREDICTOR_H_
 
 #include "base/task/single_thread_task_runner.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/mojom/lcp_critical_path_predictor/lcp_critical_path_predictor.mojom-blink.h"
 #include "third_party/blink/public/mojom/lcp_critical_path_predictor/lcp_critical_path_predictor.mojom-forward.h"
 #include "third_party/blink/renderer/core/core_export.h"
@@ -80,6 +81,7 @@
   // LCPP hints for consumption (read path):
 
   Vector<ElementLocator> lcp_element_locators_;
+  absl::optional<std::string> first_lcp_element_locator_string_;
   HashSet<KURL> lcp_influencer_scripts_;
   Vector<KURL> fetched_fonts_;
 };
diff --git a/third_party/blink/renderer/core/style/computed_style_diff_functions.json5 b/third_party/blink/renderer/core/style/computed_style_diff_functions.json5
index b6150942..a645b73 100644
--- a/third_party/blink/renderer/core/style/computed_style_diff_functions.json5
+++ b/third_party/blink/renderer/core/style/computed_style_diff_functions.json5
@@ -251,7 +251,7 @@
                 "content-visibility", "aspect-ratio", "overflow-clip-margin",
                 "-internal-align-content-block", "orphans", "widows",
                 "scrollbar-gutter", "break-after", "break-before",
-                "break-inside", "baseline-source", "text-wrap"],
+                "break-inside", "baseline-source", "text-wrap", "app-region"],
         methods_to_diff: [
           {
             method: "VerticalAlign()",
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc
index 87a7c7559..9b471654 100644
--- a/third_party/blink/renderer/core/testing/internals.cc
+++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -123,6 +123,7 @@
 #include "third_party/blink/renderer/core/layout/layout_object.h"
 #include "third_party/blink/renderer/core/layout/layout_tree_as_text.h"
 #include "third_party/blink/renderer/core/layout/layout_view.h"
+#include "third_party/blink/renderer/core/lcp_critical_path_predictor/element_locator.h"
 #include "third_party/blink/renderer/core/loader/document_loader.h"
 #include "third_party/blink/renderer/core/loader/frame_loader.h"
 #include "third_party/blink/renderer/core/loader/history_item.h"
@@ -617,6 +618,12 @@
   return sink;
 }
 
+void OnLCPPredicted(ScriptPromiseResolver* resolver,
+                    const Element& lcp_element) {
+  const ElementLocator locator = element_locator::OfElement(lcp_element);
+  resolver->Resolve(element_locator::ToStringForTesting(locator));
+}
+
 }  // namespace
 
 static absl::optional<DocumentMarker::MarkerType> MarkerTypeFrom(
@@ -4016,4 +4023,15 @@
   return Vector<String>(img->creator_scripts());
 }
 
+ScriptPromise Internals::LCPPrediction(ScriptState* script_state,
+                                       Document* document) {
+  ScriptPromiseResolver* resolver =
+      MakeGarbageCollected<ScriptPromiseResolver>(script_state);
+  ScriptPromise promise = resolver->Promise();
+
+  document->AddLCPPredictedCallback(
+      WTF::BindOnce(&OnLCPPredicted, WrapPersistent(resolver)));
+  return promise;
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/testing/internals.h b/third_party/blink/renderer/core/testing/internals.h
index b15c998..efd180ab 100644
--- a/third_party/blink/renderer/core/testing/internals.h
+++ b/third_party/blink/renderer/core/testing/internals.h
@@ -631,6 +631,8 @@
   // the LCPScriptObserver Probe.
   Vector<String> getCreatorScripts(HTMLImageElement* img);
 
+  ScriptPromise LCPPrediction(ScriptState*, Document* document);
+
  private:
   Document* ContextDocument() const;
   Vector<String> IconURLs(Document*, int icon_types_mask) const;
diff --git a/third_party/blink/renderer/core/testing/internals.idl b/third_party/blink/renderer/core/testing/internals.idl
index dda8ac5..9feda14 100644
--- a/third_party/blink/renderer/core/testing/internals.idl
+++ b/third_party/blink/renderer/core/testing/internals.idl
@@ -450,4 +450,9 @@
     void setBackForwardCacheRestorationBufferSize(long maxSize);
 
     sequence<DOMString> getCreatorScripts(HTMLImageElement img);
+
+    // Wait until predicted LCP is painted. Never called if prediction is
+    // failed. Returns element_locator format string.
+    [CallWith=ScriptState] Promise<DOMString> LCPPrediction(Document document);
+
 };
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc
index cba665f..497fa8f9 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -569,7 +569,8 @@
 }
 
 const AXObject* FindAncestorWithAriaHidden(const AXObject* start) {
-  for (const AXObject* object = start; object && !object->IsWebArea();
+  for (const AXObject* object = start;
+       object && !IsA<Document>(object->GetNode());
        object = object->ParentObject()) {
     if (object->AOMPropertyOrARIAAttributeIsTrue(AOMBooleanProperty::kHidden))
       return object;
@@ -3466,11 +3467,15 @@
 }
 
 bool AXObject::ComputeIsAriaHidden(IgnoredReasons* ignored_reasons) const {
-  // The root node of a document or popup document cannot be aria-hidden.
+  // The root node of a document or popup document cannot be aria-hidden:
+  // - The root node of the main document cannot be hidden because there
+  // is no element to place aria-hidden markup on.
+  // - The root node of the popup document cannot be aria-hidden because it
+  // seems like a bad idea to not allow access to it if it's actually there and
+  // visible.
   if (IsA<Document>(GetNode())) {
     return false;
   }
-
   // aria-hidden:true works a bit like display:none.
   // * aria-hidden=true affects entire subtree.
   // * aria-hidden=false cannot override aria-hidden=true on an ancestor.
@@ -3824,8 +3829,7 @@
   // Also children of <label> elements, for accname calculation purposes.
   // This checks to see whether this is a child of one of those.
   if (Node* parent_node = LayoutTreeBuilderTraversal::Parent(*node)) {
-    if (parent_node->IsCustomElement() ||
-        ToHTMLSlotElementIfSupportsAssignmentOrNull(parent_node)) {
+    if (parent_node->IsCustomElement() || IsA<HTMLSlotElement>(parent_node)) {
       return true;
     }
     // <span>s are ignored because they are considered uninteresting. Do not add
@@ -3887,7 +3891,7 @@
   // information with their original location in the DOM. Therefore, we need to
   // ensure that in the accessibility tree no remnant information from the
   // unflattened DOM tree remains, such as the cached parent.
-  if (ToHTMLSlotElementIfSupportsAssignmentOrNull(element)) {
+  if (IsA<HTMLSlotElement>(element)) {
     return true;
   }
 
@@ -4953,9 +4957,6 @@
         AtomicString("ARIA-GRABBED"),
         AtomicString("ARIA-HIDDEN"),  // For aria-hidden=false.
         AtomicString("ARIA-KEYSHORTCUTS"),
-        AtomicString("ARIA-LABEL"),
-        AtomicString("ARIA-LABELEDBY"),
-        AtomicString("ARIA-LABELLEDBY"),
         AtomicString("ARIA-LIVE"),
         AtomicString("ARIA-OWNS"),
         AtomicString("ARIA-RELEVANT"),
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_context_mojo.cc b/third_party/blink/renderer/modules/ml/webnn/ml_context_mojo.cc
index dd0135c..888d01b 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_context_mojo.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_context_mojo.cc
@@ -128,6 +128,17 @@
                                WTF::BindOnce(std::move(callback)));
 }
 
+bool MLContextMojo::CreateWebNNGraphSync(
+    webnn::mojom::blink::GraphInfoPtr graph_info,
+    webnn::mojom::blink::CreateGraphResultPtr* out_result) {
+  // Ensures that sync methods are only called from worker threads.
+  CHECK(!IsMainThread());
+  CHECK(remote_context_.is_bound());
+
+  // Use `WebNNContext` to create `WebNNGraph` message pipe.
+  return remote_context_->CreateGraph(std::move(graph_info), out_result);
+}
+
 void MLContextMojo::OnCreateWebNNContext(
     ScriptPromiseResolver* resolver,
     blink_mojom::CreateContextResultPtr result) {
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_context_mojo.h b/third_party/blink/renderer/modules/ml/webnn/ml_context_mojo.h
index 878c29dc..4b1720f 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_context_mojo.h
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_context_mojo.h
@@ -51,6 +51,12 @@
       webnn::mojom::blink::GraphInfoPtr graph_info,
       webnn::mojom::blink::WebNNContext::CreateGraphCallback callback);
 
+  // Creates and compiles platform specific graph synchronously in the caller's
+  // thread. Returns if the compilation was successful.
+  bool CreateWebNNGraphSync(
+      webnn::mojom::blink::GraphInfoPtr graph_info,
+      webnn::mojom::blink::CreateGraphResultPtr* out_result);
+
  protected:
   // Create `WebNNContext` message pipe with `ML` mojo interface, then
   // create the context with the hardware accelerated OS machine
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph.cc
index be8f3e1..9cef803 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph.cc
@@ -154,7 +154,8 @@
   BuildAsyncImpl(named_outputs, resolver);
 }
 
-MLGraph* MLGraph::BuildSync(const MLNamedOperands& named_outputs,
+MLGraph* MLGraph::BuildSync(ScriptState* script_state,
+                            const MLNamedOperands& named_outputs,
                             ExceptionState& exception_state) {
   String error_message;
   if (!ValidateAndInitializeResourcesInfo(named_outputs, error_message)) {
@@ -162,7 +163,7 @@
                                       error_message);
     return nullptr;
   }
-  return BuildSyncImpl(named_outputs, exception_state);
+  return BuildSyncImpl(script_state, named_outputs, exception_state);
 }
 
 bool MLGraph::ValidateAndInitializeResourcesInfo(
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph.h b/third_party/blink/renderer/modules/ml/webnn/ml_graph.h
index 388f9fe..1491a20f 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph.h
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph.h
@@ -97,14 +97,16 @@
   // is if there are no validation errors, it calls BuildSyncImpl() implemented
   // by an MLGraph backend that builds the platform specific graph in the
   // caller's thread synchronously.
-  MLGraph* BuildSync(const MLNamedOperands& named_outputs,
+  MLGraph* BuildSync(ScriptState* script_state,
+                     const MLNamedOperands& named_outputs,
                      ExceptionState& exception_state);
 
   // An MLGraph backend should implement this method to build and compile a
   // platform specific graph synchronously in the caller's thread. Once the
   // platform graph is compiled, it should return a concrete MLGraph object.
   // Otherwise, it should return a nullptr and throw a DOMException accordingly.
-  virtual MLGraph* BuildSyncImpl(const MLNamedOperands& named_outputs,
+  virtual MLGraph* BuildSyncImpl(ScriptState* script_state,
+                                 const MLNamedOperands& named_outputs,
                                  ExceptionState& exception_state) = 0;
 
   // An MLGraph backend should implement this method to execute the compiled
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 990d2d1..7ba580302 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
@@ -51,19 +51,6 @@
 
 MLGraphBuilder::BackendForTesting* g_backend_for_testing = nullptr;
 
-bool IsFloatingPointType(V8MLOperandType::Enum operand_type) {
-  switch (operand_type) {
-    case V8MLOperandType::Enum::kFloat32:
-    case V8MLOperandType::Enum::kFloat16:
-      return true;
-    case V8MLOperandType::Enum::kInt32:
-    case V8MLOperandType::Enum::kUint32:
-    case V8MLOperandType::Enum::kInt8:
-    case V8MLOperandType::Enum::kUint8:
-      return false;
-  }
-}
-
 blink::V8MLOperandType::Enum ComponentOperandTypeToBlink(
     webnn::Operand::DataType type) {
   switch (type) {
@@ -347,26 +334,27 @@
   return output.value();
 }
 
-MLOperand* BuildElementWiseUnary(MLGraphBuilder* builder,
-                                 MLOperator::OperatorKind kind,
-                                 const MLOperand* input,
-                                 ExceptionState& exception_state) {
-  // The input type must be one of the floating point types. Although this
-  // constraint is not specified in current WebNN spec, there is a feature
-  // request for that: https://github.com/webmachinelearning/webnn/issues/283
-  if (!IsFloatingPointType(input->Type())) {
+MLOperand* BuildUnaryOperator(
+    MLGraphBuilder* builder,
+    ExceptionState& exception_state,
+    MLOperator::OperatorKind kind,
+    const webnn::DataTypeConstraintSet& data_type_constraint,
+    const MLOperand* input,
+    const bindings::DictionaryBase* options = nullptr) {
+  // The output tensor of unary operator has the same type and dimensions as its
+  // input tensor.
+  if (!data_type_constraint.Has(BlinkOperandTypeToComponent(input->Type()))) {
     exception_state.ThrowDOMException(
         DOMExceptionCode::kDataError,
-        "The input type must be one of the floating point types.");
+        String::Format(
+            "The input type must be one of the %s types.",
+            webnn::DataTypeConstraintToString(data_type_constraint).c_str()));
     return nullptr;
   }
-  // According to WebNN spec:
-  // https://www.w3.org/TR/webnn/#api-mlgraphbuilder-unary, the shape of the
-  // output tensor is the same as the shape of input tensor.
-  Vector<uint32_t> dims_output = input->Dimensions();
-  auto* unary = MakeGarbageCollected<MLOperator>(builder, kind);
+
+  auto* unary = MakeGarbageCollected<MLOperator>(builder, kind, options);
   auto output = MLOperand::ValidateAndCreateOutput(builder, input->Type(),
-                                                   dims_output, unary);
+                                                   input->Dimensions(), unary);
   if (!output.has_value()) {
     exception_state.ThrowDOMException(DOMExceptionCode::kDataError,
                                       output.error());
@@ -705,20 +693,12 @@
   if (!ValidateClampOptions(options, exception_state)) {
     return nullptr;
   }
-  auto* clamp = MakeGarbageCollected<MLOperator>(
-      this, MLOperator::OperatorKind::kClamp, options);
   // According to WebNN spec
   // https://www.w3.org/TR/webnn/#api-mlgraphbuilder-clamp, the output tensor of
   // clamp has the same type and dimensions as its input.
-  auto output = MLOperand::ValidateAndCreateOutput(this, input->Type(),
-                                                   input->Dimensions(), clamp);
-  if (!output.has_value()) {
-    exception_state.ThrowDOMException(DOMExceptionCode::kDataError,
-                                      output.error());
-    return nullptr;
-  }
-  clamp->Connect({input}, {output.value()});
-  return output.value();
+  return BuildUnaryOperator(
+      this, exception_state, MLOperator::OperatorKind::kClamp,
+      webnn::DataTypeConstraintSet::All(), input, options);
 }
 
 MLActivation* MLGraphBuilder::clamp(const MLClampOptions* options,
@@ -995,17 +975,29 @@
 BUILD_ELEMENTWISE_BINARY_OP(max, kMax)
 BUILD_ELEMENTWISE_BINARY_OP(pow, kPow)
 
-#define BUILD_ELEMENTWISE_UNARY_OP(op, op_kind)                           \
-  MLOperand* MLGraphBuilder::op(const MLOperand* input,                   \
-                                ExceptionState& exception_state) {        \
-    return BuildElementWiseUnary(this, MLOperator::OperatorKind::op_kind, \
-                                 input, exception_state);                 \
+#define BUILD_ELEMENTWISE_UNARY_OP(op, op_kind, data_type_constraint) \
+  MLOperand* MLGraphBuilder::op(const MLOperand* input,               \
+                                ExceptionState& exception_state) {    \
+    return BuildUnaryOperator(this, exception_state,                  \
+                              MLOperator::OperatorKind::op_kind,      \
+                              data_type_constraint, input);           \
   }
 
-BUILD_ELEMENTWISE_UNARY_OP(abs, kAbs)
-BUILD_ELEMENTWISE_UNARY_OP(ceil, kCeil)
-BUILD_ELEMENTWISE_UNARY_OP(floor, kFloor)
-BUILD_ELEMENTWISE_UNARY_OP(neg, kNeg)
+BUILD_ELEMENTWISE_UNARY_OP(abs,
+                           kAbs,
+                           Union(webnn::DataTypeConstraint::kFloat,
+                                 webnn::DataTypeConstraint::kSignedInteger))
+BUILD_ELEMENTWISE_UNARY_OP(ceil, kCeil, webnn::DataTypeConstraint::kFloat)
+BUILD_ELEMENTWISE_UNARY_OP(cos, kCos, webnn::DataTypeConstraint::kFloat)
+BUILD_ELEMENTWISE_UNARY_OP(exp, kExp, webnn::DataTypeConstraint::kFloat)
+BUILD_ELEMENTWISE_UNARY_OP(floor, kFloor, webnn::DataTypeConstraint::kFloat)
+BUILD_ELEMENTWISE_UNARY_OP(log, kLog, webnn::DataTypeConstraint::kFloat)
+BUILD_ELEMENTWISE_UNARY_OP(neg,
+                           kNeg,
+                           Union(webnn::DataTypeConstraint::kFloat,
+                                 webnn::DataTypeConstraint::kSignedInteger))
+BUILD_ELEMENTWISE_UNARY_OP(sin, kSin, webnn::DataTypeConstraint::kFloat)
+BUILD_ELEMENTWISE_UNARY_OP(tan, kTan, webnn::DataTypeConstraint::kFloat)
 
 #define BUILD_REDUCE_OP(op, op_kind)                                   \
   MLOperand* MLGraphBuilder::op(const MLOperand* input,                \
@@ -1029,15 +1021,6 @@
 MLOperand* MLGraphBuilder::elu(const MLOperand* input,
                                const MLEluOptions* options,
                                ExceptionState& exception_state) {
-  // The current spec doesn't specify the operand type constraints of elu. An
-  // issue has been filed to track it:
-  // https://github.com/webmachinelearning/webnn/issues/283.
-  if (!IsFloatingPointType(input->Type())) {
-    exception_state.ThrowDOMException(
-        DOMExceptionCode::kDataError,
-        "The type of input must be one of the floating point types.");
-    return nullptr;
-  }
   // The current spec doesn't restrict the value of alpha. An issue has been
   // filed to track it: https://github.com/webmachinelearning/webnn/issues/383
   if (options->alpha() <= 0.0f) {
@@ -1046,20 +1029,16 @@
         "The value of alpha must be greater than 0.");
     return nullptr;
   }
-  auto* elu = MakeGarbageCollected<MLOperator>(
-      this, MLOperator::OperatorKind::kElu, options);
+  // The current spec doesn't specify the operand type constraints of elu. An
+  // issue has been filed to track it:
+  // https://github.com/webmachinelearning/webnn/issues/283.
+  //
   // According to WebNN spec
   // https://www.w3.org/TR/webnn/#api-mlgraphbuilder-elu, the output tensor of
   // elu has the same type and dimensions as its input.
-  auto output = MLOperand::ValidateAndCreateOutput(this, input->Type(),
-                                                   input->Dimensions(), elu);
-  if (!output.has_value()) {
-    exception_state.ThrowDOMException(DOMExceptionCode::kDataError,
-                                      output.error());
-    return nullptr;
-  }
-  elu->Connect({input}, {output.value()});
-  return output.value();
+  return BuildUnaryOperator(this, exception_state,
+                            MLOperator::OperatorKind::kElu,
+                            webnn::DataTypeConstraint::kFloat, input, options);
 }
 
 MLActivation* MLGraphBuilder::elu(const MLEluOptions* options,
@@ -1114,26 +1093,13 @@
   // The input type must be one of the floating point types. Although this
   // constraint is not specified in current WebNN spec, there is a feature
   // request for that: https://github.com/webmachinelearning/webnn/issues/283
-  if (!IsFloatingPointType(input->Type())) {
-    exception_state.ThrowDOMException(
-        DOMExceptionCode::kDataError,
-        "The input type must be one of the floating point types.");
-    return nullptr;
-  }
-  auto* hard_swish = MakeGarbageCollected<MLOperator>(
-      this, MLOperator::OperatorKind::kHardSwish);
+  //
   // According to WebNN spec
   // https://www.w3.org/TR/webnn/#api-mlgraphbuilder-hard-swish, the output
   // tensor of hard-swish has the same type and dimensions as its input.
-  auto output = MLOperand::ValidateAndCreateOutput(
-      this, input->Type(), input->Dimensions(), hard_swish);
-  if (!output.has_value()) {
-    exception_state.ThrowDOMException(DOMExceptionCode::kDataError,
-                                      output.error());
-    return nullptr;
-  }
-  hard_swish->Connect({input}, {output.value()});
-  return output.value();
+  return BuildUnaryOperator(this, exception_state,
+                            MLOperator::OperatorKind::kHardSwish,
+                            webnn::DataTypeConstraint::kFloat, input);
 }
 
 MLActivation* MLGraphBuilder::hardSwish(ExceptionState& exception_state) {
@@ -1149,27 +1115,13 @@
   // The current spec doesn't specify the operand type constraints of leakyRelu.
   // An issue has been filed to track it:
   // https://github.com/webmachinelearning/webnn/issues/283.
-  if (!IsFloatingPointType(input->Type())) {
-    exception_state.ThrowDOMException(
-        DOMExceptionCode::kDataError,
-        "The type of input must be one of the floating point types.");
-    return nullptr;
-  }
-
-  auto* leaky_relu = MakeGarbageCollected<MLOperator>(
-      this, MLOperator::OperatorKind::kLeakyRelu, options);
+  //
   // According to WebNN spec
   // https://www.w3.org/TR/webnn/#api-mlgraphbuilder-relu, the output tensor of
   // relu has the same type and dimensions as its input.
-  auto output = MLOperand::ValidateAndCreateOutput(
-      this, input->Type(), input->Dimensions(), leaky_relu);
-  if (!output.has_value()) {
-    exception_state.ThrowDOMException(DOMExceptionCode::kDataError,
-                                      output.error());
-    return nullptr;
-  }
-  leaky_relu->Connect({input}, {output.value()});
-  return output.value();
+  return BuildUnaryOperator(this, exception_state,
+                            MLOperator::OperatorKind::kLeakyRelu,
+                            webnn::DataTypeConstraint::kFloat, input, options);
 }
 
 MLActivation* MLGraphBuilder::leakyRelu(const MLLeakyReluOptions* options,
@@ -1287,20 +1239,12 @@
 
 MLOperand* MLGraphBuilder::relu(const MLOperand* input,
                                 ExceptionState& exception_state) {
-  auto* relu =
-      MakeGarbageCollected<MLOperator>(this, MLOperator::OperatorKind::kRelu);
   // According to WebNN spec
   // https://www.w3.org/TR/webnn/#api-mlgraphbuilder-relu, the output tensor of
   // relu has the same type and dimensions as its input.
-  auto output = MLOperand::ValidateAndCreateOutput(this, input->Type(),
-                                                   input->Dimensions(), relu);
-  if (!output.has_value()) {
-    exception_state.ThrowDOMException(DOMExceptionCode::kDataError,
-                                      output.error());
-    return nullptr;
-  }
-  relu->Connect({input}, {output.value()});
-  return output.value();
+  return BuildUnaryOperator(this, exception_state,
+                            MLOperator::OperatorKind::kRelu,
+                            webnn::DataTypeConstraintSet::All(), input);
 }
 
 MLActivation* MLGraphBuilder::relu(ExceptionState& exception_state) {
@@ -1447,27 +1391,13 @@
 
 MLOperand* MLGraphBuilder::sigmoid(const MLOperand* input,
                                    ExceptionState& exception_state) {
-  auto* sigmoid = MakeGarbageCollected<MLOperator>(
-      this, MLOperator::OperatorKind::kSigmoid);
   // According to WebNN spec
   // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-sigmoid, the
   // output tensor of sigmoid has the same type and dimensions as its input.
   // And the input type must be one of the floating point types.
-  if (!IsFloatingPointType(input->Type())) {
-    exception_state.ThrowDOMException(
-        DOMExceptionCode::kDataError,
-        "The input type must be one of the floating point types.");
-    return nullptr;
-  }
-  auto output = MLOperand::ValidateAndCreateOutput(
-      this, input->Type(), input->Dimensions(), sigmoid);
-  if (!output.has_value()) {
-    exception_state.ThrowDOMException(DOMExceptionCode::kDataError,
-                                      output.error());
-    return nullptr;
-  }
-  sigmoid->Connect({input}, {output.value()});
-  return output.value();
+  return BuildUnaryOperator(this, exception_state,
+                            MLOperator::OperatorKind::kSigmoid,
+                            webnn::DataTypeConstraint::kFloat, input);
 }
 
 MLActivation* MLGraphBuilder::sigmoid(ExceptionState& exception_state) {
@@ -1535,6 +1465,27 @@
                                             MLOperator::OperatorKind::kSoftmax);
 }
 
+MLOperand* MLGraphBuilder::softsign(const MLOperand* input,
+                                    ExceptionState& exception_state) {
+  // The input type must be one of the floating point types.
+  // The current spec doesn't specify the operand type constraints of softsign,
+  // an issue has been filed to track it-
+  // https://github.com/webmachinelearning/webnn/issues/283.
+  //
+  // According to WebNN spec
+  // https://www.w3.org/TR/webnn/#api-mlgraphbuilder-softsign, the output tensor
+  // of softsign has the same type and dimensions as its input.
+  return BuildUnaryOperator(this, exception_state,
+                            MLOperator::OperatorKind::kSoftsign,
+                            webnn::DataTypeConstraint::kFloat, input);
+}
+
+MLActivation* MLGraphBuilder::softsign(ExceptionState& exception_state) {
+  // Create the softsign operator that would be used as an activation function.
+  return MakeGarbageCollected<MLActivation>(
+      this, MLOperator::OperatorKind::kSoftsign);
+}
+
 HeapVector<Member<const MLOperand>> MLGraphBuilder::split(
     const MLOperand* input,
     const uint32_t splits,
@@ -1612,26 +1563,13 @@
   // The current spec doesn't specify the operand type constraints of tanh, an
   // issue has been filed to track it-
   // https://github.com/webmachinelearning/webnn/issues/283.
-  if (!IsFloatingPointType(input->Type())) {
-    exception_state.ThrowDOMException(
-        DOMExceptionCode::kDataError,
-        "The input type must be one of the floating point types.");
-    return nullptr;
-  }
-  auto* tanh =
-      MakeGarbageCollected<MLOperator>(this, MLOperator::OperatorKind::kTanh);
+  //
   // According to WebNN spec
   // https://www.w3.org/TR/webnn/#api-mlgraphbuilder-tanh, the output tensor of
   // tanh has the same type and dimensions as its input.
-  auto output = MLOperand::ValidateAndCreateOutput(this, input->Type(),
-                                                   input->Dimensions(), tanh);
-  if (!output.has_value()) {
-    exception_state.ThrowDOMException(DOMExceptionCode::kDataError,
-                                      output.error());
-    return nullptr;
-  }
-  tanh->Connect({input}, {output.value()});
-  return output.value();
+  return BuildUnaryOperator(this, exception_state,
+                            MLOperator::OperatorKind::kTanh,
+                            webnn::DataTypeConstraint::kFloat, input);
 }
 
 MLActivation* MLGraphBuilder::tanh(ExceptionState& exception_state) {
@@ -1732,17 +1670,32 @@
   return promise;
 }
 
-MLGraph* MLGraphBuilder::buildSync(const MLNamedOperands& named_outputs,
+MLGraph* MLGraphBuilder::buildSync(ScriptState* script_state,
+                                   const MLNamedOperands& named_outputs,
                                    ExceptionState& exception_state) {
   if (g_backend_for_testing) {
-    return g_backend_for_testing->BuildGraphSyncImpl(ml_context_, named_outputs,
-                                                     exception_state);
+    return g_backend_for_testing->BuildGraphSyncImpl(
+        script_state, ml_context_, named_outputs, exception_state);
   }
 
 #if BUILDFLAG(BUILD_WEBNN_WITH_XNNPACK)
   if (ml_context_->GetDeviceType() == V8MLDeviceType::Enum::kCpu) {
-    return MLGraphXnnpack::ValidateAndBuildSync(ml_context_, named_outputs,
-                                                exception_state);
+    return MLGraphXnnpack::ValidateAndBuildSync(script_state, ml_context_,
+                                                named_outputs, exception_state);
+  }
+#endif
+
+#if !BUILDFLAG(IS_CHROMEOS)
+  // GPU support requires a cross-process WebNN acceleration service. This
+  // services is gated behind the EnableMachineLearningNeuralNetworkService
+  // runtime feature.
+  if (ml_context_->GetDeviceType() == V8MLDeviceType::Enum::kGpu &&
+      base::FeatureList::IsEnabled(
+          webnn::features::kEnableMachineLearningNeuralNetworkService)) {
+    MLContextMojo* ml_context_mojo =
+        static_cast<MLContextMojo*>(ml_context_.Get());
+    return MLGraphMojo::ValidateAndBuildSync(script_state, ml_context_mojo,
+                                             named_outputs, exception_state);
   }
 #endif
 
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h
index 163c032..6e8b84ab 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h
@@ -149,8 +149,13 @@
   // Element-wise unary operations
   MLOperand* abs(const MLOperand* input, ExceptionState& exception_state);
   MLOperand* ceil(const MLOperand* input, ExceptionState& exception_state);
+  MLOperand* cos(const MLOperand* input, ExceptionState& exception_state);
+  MLOperand* exp(const MLOperand* input, ExceptionState& exception_state);
   MLOperand* floor(const MLOperand* input, ExceptionState& exception_state);
+  MLOperand* log(const MLOperand* input, ExceptionState& exception_state);
   MLOperand* neg(const MLOperand* input, ExceptionState& exception_state);
+  MLOperand* sin(const MLOperand* input, ExceptionState& exception_state);
+  MLOperand* tan(const MLOperand* input, ExceptionState& exception_state);
 
   MLOperand* elu(const MLOperand* input,
                  const MLEluOptions* options,
@@ -248,6 +253,9 @@
   MLOperand* softmax(const MLOperand* input, ExceptionState& exception_state);
   MLActivation* softmax(ExceptionState& exception_state);
 
+  MLOperand* softsign(const MLOperand* input, ExceptionState& exception_state);
+  MLActivation* softsign(ExceptionState& exception_state);
+
   HeapVector<Member<const MLOperand>> split(const MLOperand* input,
                                             const uint32_t splits,
                                             const MLSplitOptions* options,
@@ -268,7 +276,8 @@
                       const MLNamedOperands& outputs,
                       ExceptionState& exception_state);
 
-  MLGraph* buildSync(const MLNamedOperands& named_outputs,
+  MLGraph* buildSync(ScriptState* script_state,
+                     const MLNamedOperands& named_outputs,
                      ExceptionState& exception_state);
 
   // The test cases can override the graph building behavior by implementing
@@ -279,7 +288,8 @@
                                      const MLNamedOperands& named_outputs,
                                      ScriptPromiseResolver* resolver) = 0;
 
-    virtual MLGraph* BuildGraphSyncImpl(MLContext* context,
+    virtual MLGraph* BuildGraphSyncImpl(ScriptState* script_state,
+                                        MLContext* context,
                                         const MLNamedOperands& named_outputs,
                                         ExceptionState& exception_state) = 0;
   };
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl
index f6c56c69..5d541a72 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl
@@ -141,8 +141,13 @@
   // Element-wise unary operations
   [RaisesException] MLOperand abs(MLOperand x);
   [RaisesException] MLOperand ceil(MLOperand x);
+  [RaisesException] MLOperand cos(MLOperand x);
+  [RaisesException] MLOperand exp(MLOperand x);
   [RaisesException] MLOperand floor(MLOperand x);
+  [RaisesException] MLOperand log(MLOperand x);
   [RaisesException] MLOperand neg(MLOperand x);
+  [RaisesException] MLOperand sin(MLOperand x);
+  [RaisesException] MLOperand tan(MLOperand x);
 
   [RaisesException] MLOperand elu(MLOperand x, optional MLEluOptions options = {});
   [RaisesException] MLActivation elu(optional MLEluOptions options = {});
@@ -193,6 +198,9 @@
 
   [RaisesException] MLOperand softmax(MLOperand input);
 
+  [RaisesException] MLOperand softsign(MLOperand input);
+  [RaisesException] MLActivation softsign();
+
   [RaisesException] sequence<MLOperand> split(MLOperand input, [EnforceRange] unsigned long splits, optional MLSplitOptions options = {});
   [RaisesException] sequence<MLOperand> split(MLOperand input, sequence<[EnforceRange] unsigned long> splits, optional MLSplitOptions options = {});
 
@@ -206,6 +214,7 @@
   ] Promise<MLGraph> build(MLNamedOperands outputs);
 
   [
+    CallWith=ScriptState,
     RaisesException,
     Exposed=DedicatedWorker
   ] MLGraph buildSync(MLNamedOperands outputs);
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.cc
index 1a38548..fd313686 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.cc
@@ -2553,7 +2553,7 @@
     EXPECT_EQ(output, nullptr);
     EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
               DOMExceptionCode::kDataError);
-    EXPECT_EQ("The input type must be one of the floating point types.",
+    EXPECT_EQ("The input type must be one of the float32,float16 types.",
               scope.GetExceptionState().Message());
   }
   {
@@ -2945,113 +2945,245 @@
   }
 }
 
-void TestBuildElementWiseUnary(V8TestingScope& scope,
-                               MLGraphBuilder* builder,
-                               ElementWiseUnaryKind kind,
-                               const MLOperand* input) {
-  MLOperand* output = nullptr;
-  switch (kind) {
-    case ElementWiseUnaryKind::kAbs:
-      output = builder->abs(input, scope.GetExceptionState());
-      break;
-    case ElementWiseUnaryKind::kCeil:
-      output = builder->ceil(input, scope.GetExceptionState());
-      break;
-    case ElementWiseUnaryKind::kFloor:
-      output = builder->floor(input, scope.GetExceptionState());
-      break;
-    case ElementWiseUnaryKind::kNeg:
-      output = builder->neg(input, scope.GetExceptionState());
-      break;
+template <typename T>
+struct ElementWiseUnaryTester {
+  ElementWiseUnaryKind kind;
+  OperandInfo<T> input_info;
+
+  MLOperand* BuildElementWiseUnary(V8TestingScope& scope) {
+    auto* builder =
+        CreateMLGraphBuilder(scope.GetExecutionContext(),
+                             scope.GetScriptState(), scope.GetExceptionState());
+    auto* input = BuildInput(builder, "input", input_info.dimensions,
+                             input_info.type, scope.GetExceptionState());
+    MLOperand* output = nullptr;
+    switch (kind) {
+      case ElementWiseUnaryKind::kAbs:
+        output = builder->abs(input, scope.GetExceptionState());
+        break;
+      case ElementWiseUnaryKind::kCeil:
+        output = builder->ceil(input, scope.GetExceptionState());
+        break;
+      case ElementWiseUnaryKind::kCos:
+        output = builder->cos(input, scope.GetExceptionState());
+        break;
+      case ElementWiseUnaryKind::kExp:
+        output = builder->exp(input, scope.GetExceptionState());
+        break;
+      case ElementWiseUnaryKind::kFloor:
+        output = builder->floor(input, scope.GetExceptionState());
+        break;
+      case ElementWiseUnaryKind::kLog:
+        output = builder->log(input, scope.GetExceptionState());
+        break;
+      case ElementWiseUnaryKind::kNeg:
+        output = builder->neg(input, scope.GetExceptionState());
+        break;
+      case ElementWiseUnaryKind::kSin:
+        output = builder->sin(input, scope.GetExceptionState());
+        break;
+      case ElementWiseUnaryKind::kTan:
+        output = builder->tan(input, scope.GetExceptionState());
+        break;
+    }
+    return output;
   }
-  EXPECT_NE(output, nullptr);
-  EXPECT_EQ(output->Kind(), MLOperand::OperandKind::kOutput);
-  EXPECT_EQ(output->Type(), input->Type());
-  EXPECT_EQ(output->Dimensions(), input->Dimensions());
-  auto* op = output->Operator();
-  EXPECT_NE(op, nullptr);
-  switch (kind) {
-    case ElementWiseUnaryKind::kAbs:
-      EXPECT_EQ(op->Kind(), MLOperator::OperatorKind::kAbs);
-      break;
-    case ElementWiseUnaryKind::kCeil:
-      EXPECT_EQ(op->Kind(), MLOperator::OperatorKind::kCeil);
-      break;
-    case ElementWiseUnaryKind::kFloor:
-      EXPECT_EQ(op->Kind(), MLOperator::OperatorKind::kFloor);
-      break;
-    case ElementWiseUnaryKind::kNeg:
-      EXPECT_EQ(op->Kind(), MLOperator::OperatorKind::kNeg);
-      break;
+
+  // Test valid arguments of operators.
+  void Test(V8TestingScope& scope) {
+    MLOperand* output = BuildElementWiseUnary(scope);
+    EXPECT_EQ(output->Kind(), MLOperand::OperandKind::kOutput);
+    EXPECT_EQ(output->Type(), input_info.type);
+    EXPECT_EQ(output->Dimensions(), input_info.dimensions);
+    auto* op = output->Operator();
+    EXPECT_NE(op, nullptr);
+    switch (kind) {
+      case ElementWiseUnaryKind::kAbs:
+        EXPECT_EQ(op->Kind(), MLOperator::OperatorKind::kAbs);
+        break;
+      case ElementWiseUnaryKind::kCeil:
+        EXPECT_EQ(op->Kind(), MLOperator::OperatorKind::kCeil);
+        break;
+      case ElementWiseUnaryKind::kCos:
+        EXPECT_EQ(op->Kind(), MLOperator::OperatorKind::kCos);
+        break;
+      case ElementWiseUnaryKind::kExp:
+        EXPECT_EQ(op->Kind(), MLOperator::OperatorKind::kExp);
+        break;
+      case ElementWiseUnaryKind::kFloor:
+        EXPECT_EQ(op->Kind(), MLOperator::OperatorKind::kFloor);
+        break;
+      case ElementWiseUnaryKind::kLog:
+        EXPECT_EQ(op->Kind(), MLOperator::OperatorKind::kLog);
+        break;
+      case ElementWiseUnaryKind::kNeg:
+        EXPECT_EQ(op->Kind(), MLOperator::OperatorKind::kNeg);
+        break;
+      case ElementWiseUnaryKind::kSin:
+        EXPECT_EQ(op->Kind(), MLOperator::OperatorKind::kSin);
+        break;
+      case ElementWiseUnaryKind::kTan:
+        EXPECT_EQ(op->Kind(), MLOperator::OperatorKind::kTan);
+        break;
+    }
+    EXPECT_EQ(op->IsConnected(), true);
+    EXPECT_EQ(op->Options(), nullptr);
   }
-  EXPECT_EQ(op->IsConnected(), true);
-  EXPECT_EQ(op->Options(), nullptr);
-}
+};
 
 TEST_F(MLGraphBuilderTest, ElementWiseUnaryTest) {
   V8TestingScope scope;
-  auto* builder =
-      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
-                           scope.GetExceptionState());
   {
     // Test building element-wise abs.
-    const Vector<uint32_t> input_shape({1});
-    auto* input =
-        BuildInput(builder, "input", input_shape,
-                   V8MLOperandType::Enum::kFloat32, scope.GetExceptionState());
-    TestBuildElementWiseUnary(scope, builder, ElementWiseUnaryKind::kAbs,
-                              input);
+    ElementWiseUnaryTester<float>{
+        .kind = ElementWiseUnaryKind::kAbs,
+        .input_info = {.type = V8MLOperandType::Enum::kFloat32,
+                       .dimensions = {2}}}
+        .Test(scope);
   }
   {
     // Test building element-wise ceil.
-    const Vector<uint32_t> input_shape({1, 2});
-    auto* input =
-        BuildInput(builder, "input", input_shape,
-                   V8MLOperandType::Enum::kFloat32, scope.GetExceptionState());
-    TestBuildElementWiseUnary(scope, builder, ElementWiseUnaryKind::kCeil,
-                              input);
+    ElementWiseUnaryTester<float>{
+        .kind = ElementWiseUnaryKind::kCeil,
+        .input_info = {.type = V8MLOperandType::Enum::kFloat32,
+                       .dimensions = {1, 2}}}
+        .Test(scope);
+  }
+  {
+    // Test building element-wise cos.
+    ElementWiseUnaryTester<float>{
+        .kind = ElementWiseUnaryKind::kCos,
+        .input_info = {.type = V8MLOperandType::Enum::kFloat32,
+                       .dimensions = {5, 6}}}
+        .Test(scope);
+  }
+  {
+    // Test building element-wise exp.
+    ElementWiseUnaryTester<float>{
+        .kind = ElementWiseUnaryKind::kExp,
+        .input_info = {.type = V8MLOperandType::Enum::kFloat32,
+                       .dimensions = {8, 5, 6}}}
+        .Test(scope);
   }
   {
     // Test building element-wise floor.
-    const Vector<uint32_t> input_shape({1, 2, 3});
-    auto* input =
-        BuildInput(builder, "input", input_shape,
-                   V8MLOperandType::Enum::kFloat32, scope.GetExceptionState());
-    TestBuildElementWiseUnary(scope, builder, ElementWiseUnaryKind::kFloor,
-                              input);
+    ElementWiseUnaryTester<float>{
+        .kind = ElementWiseUnaryKind::kFloor,
+        .input_info = {.type = V8MLOperandType::Enum::kFloat32,
+                       .dimensions = {1, 2, 3}}}
+        .Test(scope);
+  }
+  {
+    // Test building element-wise log.
+    ElementWiseUnaryTester<float>{
+        .kind = ElementWiseUnaryKind::kLog,
+        .input_info = {.type = V8MLOperandType::Enum::kFloat32,
+                       .dimensions = {8, 6}}}
+        .Test(scope);
   }
   {
     // Test building element-wise neg.
-    const Vector<uint32_t> input_shape({1, 2, 3, 4});
-    auto* input =
-        BuildInput(builder, "input", input_shape,
-                   V8MLOperandType::Enum::kFloat32, scope.GetExceptionState());
-    TestBuildElementWiseUnary(scope, builder, ElementWiseUnaryKind::kNeg,
-                              input);
+    ElementWiseUnaryTester<float>{
+        .kind = ElementWiseUnaryKind::kNeg,
+        .input_info = {.type = V8MLOperandType::Enum::kFloat32,
+                       .dimensions = {1, 2, 3, 4}}}
+        .Test(scope);
+  }
+  {
+    // Test building element-wise sin.
+    ElementWiseUnaryTester<float>{
+        .kind = ElementWiseUnaryKind::kSin,
+        .input_info = {.type = V8MLOperandType::Enum::kFloat32,
+                       .dimensions = {6}}}
+        .Test(scope);
+  }
+  {
+    // Test building element-wise tan.
+    ElementWiseUnaryTester<float>{
+        .kind = ElementWiseUnaryKind::kTan,
+        .input_info = {.type = V8MLOperandType::Enum::kFloat32,
+                       .dimensions = {8, 6, 2}}}
+        .Test(scope);
   }
   {
     // Test throwing exception when building ceil with int32 input.
-    auto* input =
-        BuildInput(builder, "input", {3, 4}, V8MLOperandType::Enum::kInt32,
-                   scope.GetExceptionState());
-    auto* output = builder->ceil(input, scope.GetExceptionState());
+    const MLOperand* output = ElementWiseUnaryTester<int32_t>{
+        .kind = ElementWiseUnaryKind::kCeil,
+        .input_info = {
+            .type = V8MLOperandType::Enum::kInt32,
+            .dimensions = {3, 4}}}.BuildElementWiseUnary(scope);
     EXPECT_EQ(output, nullptr);
     EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
               DOMExceptionCode::kDataError);
     EXPECT_EQ(scope.GetExceptionState().Message(),
-              "The input type must be one of the floating point types.");
+              "The input type must be one of the float32,float16 types.");
+  }
+  {
+    // Test throwing exception when building exp with int32 input.
+    const MLOperand* output = ElementWiseUnaryTester<uint32_t>{
+        .kind = ElementWiseUnaryKind::kExp,
+        .input_info = {
+            .type = V8MLOperandType::Enum::kUint32,
+            .dimensions = {3, 4}}}.BuildElementWiseUnary(scope);
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "The input type must be one of the float32,float16 types.");
+  }
+  {
+    // Test throwing exception when building floor with int32 input.
+    const MLOperand* output = ElementWiseUnaryTester<int32_t>{
+        .kind = ElementWiseUnaryKind::kFloor,
+        .input_info = {
+            .type = V8MLOperandType::Enum::kInt32,
+            .dimensions = {3, 4}}}.BuildElementWiseUnary(scope);
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "The input type must be one of the float32,float16 types.");
+  }
+  {
+    // Test throwing exception when building sin with int32 input.
+    const MLOperand* output = ElementWiseUnaryTester<uint32_t>{
+        .kind = ElementWiseUnaryKind::kSin,
+        .input_info = {
+            .type = V8MLOperandType::Enum::kUint32,
+            .dimensions = {3, 4}}}.BuildElementWiseUnary(scope);
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "The input type must be one of the float32,float16 types.");
   }
   {
     // Test throwing exception when building neg with uint32 input.
-    auto* input =
-        BuildInput(builder, "input", {3, 4}, V8MLOperandType::Enum::kUint32,
-                   scope.GetExceptionState());
-    auto* output = builder->neg(input, scope.GetExceptionState());
+    const MLOperand* output = ElementWiseUnaryTester<uint32_t>{
+        .kind = ElementWiseUnaryKind::kNeg,
+        .input_info = {
+            .type = V8MLOperandType::Enum::kUint32,
+            .dimensions = {3, 4}}}.BuildElementWiseUnary(scope);
     EXPECT_EQ(output, nullptr);
     EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
               DOMExceptionCode::kDataError);
-    EXPECT_EQ(scope.GetExceptionState().Message(),
-              "The input type must be one of the floating point types.");
+    EXPECT_EQ(
+        scope.GetExceptionState().Message(),
+        "The input type must be one of the float32,float16,int32,int8 types.");
+  }
+  {
+    // Test throwing exception when building abs with uint8 input.
+    const MLOperand* output = ElementWiseUnaryTester<uint8_t>{
+        .kind = ElementWiseUnaryKind::kAbs,
+        .input_info = {
+            .type = V8MLOperandType::Enum::kUint8,
+            .dimensions = {3, 4}}}.BuildElementWiseUnary(scope);
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(
+        scope.GetExceptionState().Message(),
+        "The input type must be one of the float32,float16,int32,int8 types.");
   }
 }
 
@@ -3836,7 +3968,7 @@
     EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
               DOMExceptionCode::kDataError);
     EXPECT_EQ(scope.GetExceptionState().Message(),
-              "The type of input must be one of the floating point types.");
+              "The input type must be one of the float32,float16 types.");
   }
   {
     // Test building elu as a standalone operator.
@@ -4028,6 +4160,53 @@
   }
 }
 
+TEST_F(MLGraphBuilderTest, SoftSignTest) {
+  V8TestingScope scope;
+  auto* builder =
+      CreateMLGraphBuilder(scope.GetExecutionContext(), scope.GetScriptState(),
+                           scope.GetExceptionState());
+  {
+    // Test building softsign with float32 input.
+    Vector<uint32_t> input_shape({3, 4});
+    auto* input =
+        BuildInput(builder, "input", input_shape,
+                   V8MLOperandType::Enum::kFloat32, scope.GetExceptionState());
+    auto* output = builder->softsign(input, scope.GetExceptionState());
+    EXPECT_NE(output, nullptr);
+    EXPECT_EQ(output->Kind(), MLOperand::OperandKind::kOutput);
+    EXPECT_EQ(output->Type(), V8MLOperandType::Enum::kFloat32);
+    EXPECT_EQ(output->Dimensions(), input_shape);
+    const MLOperator* softsign = output->Operator();
+    EXPECT_NE(softsign, nullptr);
+    EXPECT_EQ(softsign->Kind(), MLOperator::OperatorKind::kSoftsign);
+    EXPECT_EQ(softsign->IsConnected(), true);
+    EXPECT_EQ(softsign->Options(), nullptr);
+  }
+  {
+    // Test throwing exception when building softsign with int32 input.
+    Vector<uint32_t> input_shape({3, 4});
+    auto* input =
+        BuildInput(builder, "input", input_shape, V8MLOperandType::Enum::kInt32,
+                   scope.GetExceptionState());
+    auto* output = builder->softsign(input, scope.GetExceptionState());
+    EXPECT_EQ(output, nullptr);
+    EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
+              DOMExceptionCode::kDataError);
+    EXPECT_EQ(scope.GetExceptionState().Message(),
+              "The input type must be one of the float32,float16 types.");
+  }
+  {
+    // Test building softsign operator.
+    auto* softsign = builder->softsign(scope.GetExceptionState());
+    EXPECT_NE(softsign, nullptr);
+    EXPECT_NE(softsign->Operator(), nullptr);
+    EXPECT_EQ(softsign->Operator()->Kind(),
+              MLOperator::OperatorKind::kSoftsign);
+    EXPECT_EQ(softsign->Operator()->IsConnected(), false);
+    EXPECT_EQ(softsign->Operator()->Options(), nullptr);
+  }
+}
+
 TEST_F(MLGraphBuilderTest, SigmoidTest) {
   V8TestingScope scope;
   auto* builder =
@@ -4061,7 +4240,7 @@
     EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
               DOMExceptionCode::kDataError);
     EXPECT_EQ(scope.GetExceptionState().Message(),
-              "The input type must be one of the floating point types.");
+              "The input type must be one of the float32,float16 types.");
   }
   {
     // Test building sigmoid operator.
@@ -4366,7 +4545,7 @@
     EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(),
               DOMExceptionCode::kDataError);
     EXPECT_EQ(scope.GetExceptionState().Message(),
-              "The input type must be one of the floating point types.");
+              "The input type must be one of the float32,float16 types.");
   }
   {
     // Test building tanh operator.
@@ -4524,11 +4703,12 @@
   }
 
   // Create and build a FakeMLGraphBackend object synchronously.
-  static MLGraph* ValidateAndBuildSync(MLContext* context,
+  static MLGraph* ValidateAndBuildSync(ScriptState* script_state,
+                                       MLContext* context,
                                        const MLNamedOperands& named_outputs,
                                        ExceptionState& exception_state) {
     return MakeGarbageCollected<FakeMLGraphBackend>(context)->BuildSync(
-        named_outputs, exception_state);
+        script_state, named_outputs, exception_state);
   }
 
   // The constructor shouldn't be called directly. The callers should use
@@ -4547,7 +4727,8 @@
 
   // Return this FakeMLGraphBackend object for testing the input and output
   // resources info.
-  MLGraph* BuildSyncImpl(const MLNamedOperands& named_outputs,
+  MLGraph* BuildSyncImpl(ScriptState* script_state,
+                         const MLNamedOperands& named_outputs,
                          ExceptionState& exception_state) override {
     return this;
   }
@@ -4588,11 +4769,12 @@
     FakeMLGraphBackend::ValidateAndBuildAsync(context, named_outputs, resolver);
   }
 
-  MLGraph* BuildGraphSyncImpl(MLContext* context,
+  MLGraph* BuildGraphSyncImpl(ScriptState* script_state,
+                              MLContext* context,
                               const MLNamedOperands& named_outputs,
                               ExceptionState& exception_state) override {
-    return FakeMLGraphBackend::ValidateAndBuildSync(context, named_outputs,
-                                                    exception_state);
+    return FakeMLGraphBackend::ValidateAndBuildSync(
+        script_state, context, named_outputs, exception_state);
   }
 };
 
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.h b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.h
index ec7dd13a..2bef32a 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.h
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.h
@@ -67,7 +67,17 @@
                                   const MLOperand* a,
                                   const MLOperand* b);
 
-enum class ElementWiseUnaryKind { kAbs, kCeil, kFloor, kNeg };
+enum class ElementWiseUnaryKind {
+  kAbs,
+  kCeil,
+  kCos,
+  kExp,
+  kFloor,
+  kLog,
+  kNeg,
+  kSin,
+  kTan
+};
 
 MLOperand* BuildPad(V8TestingScope& scope,
                     MLGraphBuilder* builder,
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_cros.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_cros.cc
index 327f386..c7875d4 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_cros.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_cros.cc
@@ -209,7 +209,8 @@
   g_flatbuffer_for_testing = flatbuffer;
 }
 
-MLGraph* MLGraphCrOS::BuildSyncImpl(const MLNamedOperands& named_outputs,
+MLGraph* MLGraphCrOS::BuildSyncImpl(ScriptState* script_state,
+                                    const MLNamedOperands& named_outputs,
                                     ExceptionState& exception_state) {
   // TODO(crbug.com/1273291): Support sync build that is only exposed to
   // dedicated worker.
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_cros.h b/third_party/blink/renderer/modules/ml/webnn/ml_graph_cros.h
index 5c0d463..13bdb2ee 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_cros.h
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_cros.h
@@ -57,7 +57,8 @@
                       ScriptPromiseResolver* resolver) override;
 
   // Load the converted model with synchronous call of `ModelLoader` interface.
-  MLGraph* BuildSyncImpl(const MLNamedOperands& named_outputs,
+  MLGraph* BuildSyncImpl(ScriptState* script_state,
+                         const MLNamedOperands& named_outputs,
                          ExceptionState& exception_state) override;
 
   // Compute the converted model with asynchronous call of `Model` interface.
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_mojo.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_mojo.cc
index 0d797d4..ec71c01 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_mojo.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_mojo.cc
@@ -127,6 +127,15 @@
   graph->BuildAsync(named_outputs, resolver);
 }
 
+// static
+MLGraph* MLGraphMojo::ValidateAndBuildSync(ScriptState* script_state,
+                                           MLContextMojo* context,
+                                           const MLNamedOperands& named_outputs,
+                                           ExceptionState& exception_state) {
+  auto* graph = MakeGarbageCollected<MLGraphMojo>(script_state, context);
+  return graph->BuildSyncImpl(script_state, named_outputs, exception_state);
+}
+
 MLGraphMojo::MLGraphMojo(ScriptState* script_state, MLContextMojo* context)
     : MLGraph(context),
       ml_context_mojo_(context),
@@ -156,14 +165,38 @@
                     WrapPersistent(resolver)));
 }
 
-MLGraph* MLGraphMojo::BuildSyncImpl(const MLNamedOperands& named_outputs,
+MLGraph* MLGraphMojo::BuildSyncImpl(ScriptState* script_state,
+                                    const MLNamedOperands& outputs,
                                     ExceptionState& exception_state) {
-  // TODO(crbug.com/1273291): Support sync build that is only exposed to
-  // dedicated worker.
-  NOTIMPLEMENTED();
-  exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
-                                    "Sync build not implemented.");
-  return nullptr;
+  // Ensures that this sync method is only called from worker threads.
+  CHECK(!IsMainThread());
+  auto graph_info = BuildWebNNGraphInfo(outputs);
+  if (!graph_info.has_value()) {
+    exception_state.ThrowDOMException(
+        DOMExceptionCode::kDataError,
+        "Failed to build graph: " + graph_info.error());
+    return nullptr;
+  }
+
+  blink_mojom::CreateGraphResultPtr result;
+  if (!ml_context_mojo_->CreateWebNNGraphSync(std::move(graph_info.value()),
+                                              &result)) {
+    exception_state.ThrowDOMException(DOMExceptionCode::kOperationError,
+                                      "Failed to build graph.");
+  }
+  if (result->is_error()) {
+    const auto& create_graph_error = result->get_error();
+    exception_state.ThrowDOMException(
+        ConvertWebNNErrorCodeToDOMExceptionCode(create_graph_error->error_code),
+        create_graph_error->error_message);
+    return nullptr;
+  }
+
+  auto* execution_context = ExecutionContext::From(script_state);
+  remote_graph_.Bind(
+      std::move(result->get_graph_remote()),
+      execution_context->GetTaskRunner(TaskType::kInternalDefault));
+  return this;
 }
 
 void MLGraphMojo::ComputeAsyncImpl(const MLNamedArrayBufferViews& inputs,
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_mojo.h b/third_party/blink/renderer/modules/ml/webnn/ml_graph_mojo.h
index 654f1101..c35df2e 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_mojo.h
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_mojo.h
@@ -23,12 +23,17 @@
  public:
   // Create and build an MLGraphMojo object. Resolve the promise with
   // this concrete object if the graph builds successfully out of renderer
-  // process. Launch WebNN service and bind `WebNNContext` mojo interface
-  // to create `WebNNGraph` message pipe if needed.
+  // process.
   static void ValidateAndBuildAsync(MLContextMojo* context,
                                     const MLNamedOperands& named_outputs,
                                     ScriptPromiseResolver* resolver);
 
+  // Create and build an MLGraphMojo object.
+  static MLGraph* ValidateAndBuildSync(ScriptState* script_state,
+                                       MLContextMojo* context,
+                                       const MLNamedOperands& named_outputs,
+                                       ExceptionState& exception_state);
+
   MLGraphMojo(ScriptState* script_state, MLContextMojo* context);
   ~MLGraphMojo() override;
 
@@ -41,7 +46,8 @@
   void BuildAsyncImpl(const MLNamedOperands& outputs,
                       ScriptPromiseResolver* resolver) override;
 
-  MLGraph* BuildSyncImpl(const MLNamedOperands& named_outputs,
+  MLGraph* BuildSyncImpl(ScriptState* script_state,
+                         const MLNamedOperands& named_outputs,
                          ExceptionState& exception_state) override;
 
   void ComputeAsyncImpl(const MLNamedArrayBufferViews& inputs,
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test.cc
index 3ef6079..8c0605b 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test.cc
@@ -309,13 +309,28 @@
         output_operand =
             builder->ceil(input_operand, scope.GetExceptionState());
         break;
+      case ElementWiseUnaryKind::kCos:
+        output_operand = builder->cos(input_operand, scope.GetExceptionState());
+        break;
+      case ElementWiseUnaryKind::kExp:
+        output_operand = builder->exp(input_operand, scope.GetExceptionState());
+        break;
       case ElementWiseUnaryKind::kFloor:
         output_operand =
             builder->floor(input_operand, scope.GetExceptionState());
         break;
+      case ElementWiseUnaryKind::kLog:
+        output_operand = builder->log(input_operand, scope.GetExceptionState());
+        break;
       case ElementWiseUnaryKind::kNeg:
         output_operand = builder->neg(input_operand, scope.GetExceptionState());
         break;
+      case ElementWiseUnaryKind::kSin:
+        output_operand = builder->sin(input_operand, scope.GetExceptionState());
+        break;
+      case ElementWiseUnaryKind::kTan:
+        output_operand = builder->tan(input_operand, scope.GetExceptionState());
+        break;
     }
     auto [graph, build_exception] =
         helper.BuildGraph(scope, builder, {{"output", output_operand}});
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_base.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_base.cc
index 27e7757..ecea2f5 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_base.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_base.cc
@@ -81,8 +81,8 @@
       }
     }
     case ExecutionMode::kSync: {
-      auto* graph =
-          builder->buildSync(named_operands, scope.GetExceptionState());
+      auto* graph = builder->buildSync(scope.GetScriptState(), named_operands,
+                                       scope.GetExceptionState());
       if (graph) {
         return BuildResult{.graph = static_cast<MLGraph*>(graph),
                            .exception = nullptr};
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.cc
index caf55cb..8fdf77e 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.cc
@@ -1900,11 +1900,12 @@
 
 // static
 MLGraph* MLGraphXnnpack::ValidateAndBuildSync(
+    ScriptState* script_state,
     MLContext* context,
     const MLNamedOperands& named_outputs,
     ExceptionState& exception_state) {
   return MakeGarbageCollected<MLGraphXnnpack>(context)->BuildSync(
-      named_outputs, exception_state);
+      script_state, named_outputs, exception_state);
 }
 
 MLGraphXnnpack::MLGraphXnnpack(MLContext* context)
@@ -2040,7 +2041,8 @@
   resolver->Resolve(this);
 }
 
-MLGraph* MLGraphXnnpack::BuildSyncImpl(const MLNamedOperands& named_outputs,
+MLGraph* MLGraphXnnpack::BuildSyncImpl(ScriptState* script_state,
+                                       const MLNamedOperands& named_outputs,
                                        ExceptionState& exception_state) {
   CHECK(!xnn_runtime_wrapper_);
   String error_message;
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.h b/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.h
index f8b22f1..962d060 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.h
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.h
@@ -46,7 +46,8 @@
   // Create and build a MLGraphXnnpack object synchronously in the caller's
   // thread. Return this concrete object if the underlying XNNPACK subgraph
   // builds successfully.
-  static MLGraph* ValidateAndBuildSync(MLContext* context,
+  static MLGraph* ValidateAndBuildSync(ScriptState* script_state,
+                                       MLContext* context,
                                        const MLNamedOperands& named_outputs,
                                        ExceptionState& exception_state);
 
@@ -120,7 +121,8 @@
   // thread. If the XNNPACK Subgraph and Runtime build successfully, it should
   // return this `MLGraphXnnpack` object. Otherwise, it returns a nullptr and
   // throw a DOMException accordingly.
-  MLGraph* BuildSyncImpl(const MLNamedOperands& named_outputs,
+  MLGraph* BuildSyncImpl(ScriptState* script_state,
+                         const MLNamedOperands& named_outputs,
                          ExceptionState& exception_state) override;
 
   // Post the XNNPACK Runtime object invocation to a background thread. The
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_operator.cc b/third_party/blink/renderer/modules/ml/webnn/ml_operator.cc
index a599b2a2..1fcf9334 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_operator.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_operator.cc
@@ -32,10 +32,20 @@
       return "abs";
     case MLOperator::OperatorKind::kCeil:
       return "ceil";
+    case MLOperator::OperatorKind::kCos:
+      return "cos";
+    case MLOperator::OperatorKind::kExp:
+      return "exp";
     case MLOperator::OperatorKind::kFloor:
       return "floor";
+    case MLOperator::OperatorKind::kLog:
+      return "log";
     case MLOperator::OperatorKind::kNeg:
       return "neg";
+    case MLOperator::OperatorKind::kSin:
+      return "sin";
+    case MLOperator::OperatorKind::kTan:
+      return "tan";
     case MLOperator::OperatorKind::kLeakyRelu:
       return "leakyRelu";
     case MLOperator::OperatorKind::kMax:
@@ -88,6 +98,8 @@
       return "resample2d";
     case MLOperator::OperatorKind::kSigmoid:
       return "sigmoid";
+    case MLOperator::OperatorKind::kSoftsign:
+      return "softsign";
     case MLOperator::OperatorKind::kSlice:
       return "slice";
     case MLOperator::OperatorKind::kSoftmax:
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_operator.h b/third_party/blink/renderer/modules/ml/webnn/ml_operator.h
index 61d627c..9b0e2c9 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_operator.h
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_operator.h
@@ -31,8 +31,13 @@
     kDiv,
     kAbs,
     kCeil,
+    kCos,
+    kExp,
     kFloor,
+    kLog,
     kNeg,
+    kSin,
+    kTan,
     kLeakyRelu,
     kMax,
     kMin,
@@ -61,6 +66,7 @@
     kSigmoid,
     kSlice,
     kSoftmax,
+    kSoftsign,
     kSplit,
     kTanh,
     kTranspose
diff --git a/third_party/blink/tools/blinkpy/w3c/test_importer.py b/third_party/blink/tools/blinkpy/w3c/test_importer.py
index 92fa8f9..526c2f2 100644
--- a/third_party/blink/tools/blinkpy/w3c/test_importer.py
+++ b/third_party/blink/tools/blinkpy/w3c/test_importer.py
@@ -245,17 +245,16 @@
 
         if try_results and self.git_cl.some_failed(try_results):
             self.fetch_new_expectations_and_baselines()
-            if self.project_git.has_working_directory_changes():
-                # Skip slow and timeout tests so that presubmit check passes
-                port = self.host.port_factory.get()
-                if self.expectations_updater.skip_slow_timeout_tests(port):
-                    path = port.path_to_generic_test_expectations_file()
-                    self.project_git.add_list([path])
+            # Skip slow and timeout tests so that presubmit check passes
+            port = self.host.port_factory.get()
+            if self.expectations_updater.skip_slow_timeout_tests(port):
+                path = port.path_to_generic_test_expectations_file()
+                self.project_git.add_list([path])
 
-                self._generate_manifest()
-                message = 'Update test expectations and baselines.'
-                self._commit_changes(message)
-                self._upload_patchset(message)
+            self._generate_manifest()
+            message = 'Update test expectations and baselines.'
+            self._commit_changes(message)
+            self._upload_patchset(message)
         return True
 
     def _trigger_try_jobs(self):
diff --git a/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py b/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py
index d5b5f3e..705a704 100644
--- a/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py
+++ b/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py
@@ -164,6 +164,9 @@
             'INFO:   cq-builder-b\n',
             'INFO:   cq-wpt-builder-c\n',
             'INFO: All jobs finished.\n',
+            'INFO: Skip Slow and Timeout tests.\n',
+            'INFO: Generating MANIFEST.json\n',
+            'INFO: Committing changes.\n',
         ])
 
     def test_run_commit_queue_for_cl_pass(self):
diff --git a/third_party/blink/tools/blinkpy/wpt_tests/wpt_adapter.py b/third_party/blink/tools/blinkpy/wpt_tests/wpt_adapter.py
index 21ce75e..64134e4 100644
--- a/third_party/blink/tools/blinkpy/wpt_tests/wpt_adapter.py
+++ b/third_party/blink/tools/blinkpy/wpt_tests/wpt_adapter.py
@@ -84,9 +84,12 @@
         return super().suite_start(data)
 
     def suite_end(self, data) -> str:
-        # Do not show test failures again in noninteractive mode. They are
-        # already shown during the run.
+        # Do not show test failures or flakes again in noninteractive mode.
+        # They are already shown during the run. We also don't need to
+        # differentiate between the primary expectation and "known
+        # intermittent" statuses.
         self.test_failure_text = ''
+        self.known_intermittent_results.clear()
         return super().suite_end(data)
 
 
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests
index 7f55ea03..9cd41a56 100644
--- a/third_party/blink/web_tests/NeverFixTests
+++ b/third_party/blink/web_tests/NeverFixTests
@@ -2076,6 +2076,7 @@
 [ Chrome ] external/wpt/bluetooth/* [ Skip ]
 [ Chrome ] wpt_internal/bluetooth/* [ Skip ]
 [ Chrome ] external/wpt/fledge/* [ Skip ]
+[ Chrome ] wpt_internal/import-maps/* [ Skip ]
 [ Chrome ] external/wpt/speculation-rules/prerender/* [ Skip ]
 [ Chrome ] external/wpt/speculation-rules/prerender/credentialed-prerender-not-opt-in.html [ Pass ]
 [ Chrome ] external/wpt/speculation-rules/prerender/csp-script-src-self.html [ Pass ]
@@ -2086,3 +2087,14 @@
 [ Chrome ] external/wpt/speculation-rules/prerender/response-code-non-successful.html?code=402 [ Pass ]
 [ Chrome ] external/wpt/speculation-rules/prerender/response-code-non-successful.html?code=500 [ Pass ]
 [ Chrome ] external/wpt/speculation-rules/prerender/response-code-successful.html?code=202 [ Pass ]
+
+crbug.com/1499775 [ Chrome ] external/wpt/html/cross-origin-opener-policy/iframe-popup-same-origin-allow-popups-to-same-origin-allow-popups.https.html?7-8 [ Skip ] # harness error
+crbug.com/1499775 [ Chrome ] external/wpt/html/cross-origin-opener-policy/iframe-popup-same-origin-allow-popups-to-same-origin.https.html?5-6 [ Skip ] # harness error
+crbug.com/1499775 [ Chrome ] external/wpt/html/cross-origin-opener-policy/iframe-popup-same-origin-to-unsafe-none.https.html?7-8 [ Skip ] # harness error
+crbug.com/1499775 [ Chrome ] external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/iframe-popup-to-soap.https.html?3-4 [ Skip ] # harness error
+crbug.com/1499775 [ Chrome ] external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties/iframe-popup-to-soap.https.html?5-6 [ Skip ] # harness error
+crbug.com/1499775 [ Chrome ] external/wpt/notifications/getnotifications-across-processes.https.window.html [ Skip ]
+crbug.com/1499775 [ Chrome ] external/wpt/screen-orientation/lock-sandboxed-iframe.html [ Skip ]
+crbug.com/1499775 [ Chrome ] wpt_internal/webmidi/loopback-receive.https.html [ Skip ]
+crbug.com/1499775 [ Chrome ] wpt_internal/webmidi/loopback-with-timestamp.https.html [ Skip ]
+crbug.com/1499775 [ Chrome ] wpt_internal/webmidi/requestmidiaccess-upgrade.https.html [ Skip ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 25cf2be6..f592d129 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -2619,6 +2619,10 @@
 external/wpt/webdriver/tests/bidi/network/response_started/response_started_cached.py [ Timeout ]
 
 # ====== Test expectations added to unblock wpt-importer ======
+crbug.com/626703 external/wpt/css/css-text/text-align/text-align-justify-tabs-001.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/text-align/text-align-justify-tabs-002.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/text-align/text-align-justify-tabs-003.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/text-align/text-align-justify-tabs-004.html [ Failure ]
 crbug.com/626703 external/wpt/xhr/send-authentication-basic-repeat-no-args.htm [ Failure ]
 crbug.com/626703 external/wpt/xhr/send-authentication-basic-setrequestheader-and-arguments.htm [ Failure ]
 crbug.com/626703 external/wpt/xhr/send-authentication-basic-setrequestheader.htm [ Failure ]
@@ -5270,7 +5274,9 @@
 
 # Flaky on Mac and Windows
 crbug.com/1272199 external/wpt/websockets/stream/tentative/backpressure-receive.any.serviceworker.html?wpt_flags=h2 [ Failure Pass ]
-crbug.com/1272203 external/wpt/websockets/stream/tentative/backpressure-send.any.serviceworker.html?wpt_flags=h2 [ Failure Pass ]
+crbug.com/1272203 [ Win ] external/wpt/websockets/stream/tentative/backpressure-send.any.serviceworker.html?wpt_flags=h2 [ Failure Pass ]
+crbug.com/1272203 [ Mac ] external/wpt/websockets/stream/tentative/backpressure-send.any.serviceworker.html?wpt_flags=h2 [ Failure Pass ]
+crbug.com/1272203 [ Linux ] external/wpt/websockets/stream/tentative/backpressure-send.any.serviceworker.html?wpt_flags=h2 [ Failure Pass ]
 
 # Times out flakily on all platforms. Previously marked slow, crbug.com/874695.
 crbug.com/1272801 http/tests/permissions/chromium/test-request-sharedworker.html [ Pass Timeout ]
@@ -5787,7 +5793,9 @@
 crbug.com/1445674 [ Linux ] webaudio/internals/audioworkletprocessor-gc.https.html [ Timeout ]
 crbug.com/1463024 [ Debug Linux ] fast/forms/date/date-input-vertical-lr.html [ Failure ]
 crbug.com/1463024 [ Debug Linux ] fast/forms/date/date-input-vertical-rl.html [ Failure ]
-crbug.com/1407279 external/wpt/fullscreen/api/element-request-fullscreen-cross-origin.sub.html [ Failure ]
+crbug.com/1407279 [ Win ] external/wpt/fullscreen/api/element-request-fullscreen-cross-origin.sub.html [ Failure ]
+crbug.com/1407279 [ Mac ] external/wpt/fullscreen/api/element-request-fullscreen-cross-origin.sub.html [ Failure ]
+crbug.com/1407279 [ Linux ] external/wpt/fullscreen/api/element-request-fullscreen-cross-origin.sub.html [ Failure ]
 crbug.com/1454956 [ Linux ] external/wpt/mediacapture-record/MediaRecorder-canvas-media-source.https.html [ Failure ]
 crbug.com/1454956 [ Mac ] virtual/gpu/external/wpt/mediacapture-record/MediaRecorder-canvas-media-source.https.html [ Failure ]
 crbug.com/1345886 [ Linux ] plugins/user-gesture.html [ Failure ]
@@ -6731,7 +6739,9 @@
 crbug.com/1453977 [ Linux ] fast/events/touch/gesture/gesture-tap-paragraph-end.html [ Failure Pass ]
 crbug.com/1454064 [ Debug Linux ] fast/events/autoscroll-should-not-stop-on-keypress.html [ Failure Pass ]
 
-crbug.com/1453772 external/wpt/window-management/multi-screen-fullscreen-companion.tentative.https.html [ Failure Pass ]
+crbug.com/1453772 [ Win ] external/wpt/window-management/multi-screen-fullscreen-companion.tentative.https.html [ Failure Pass ]
+crbug.com/1453772 [ Mac ] external/wpt/window-management/multi-screen-fullscreen-companion.tentative.https.html [ Failure Pass ]
+crbug.com/1453772 [ Linux ] external/wpt/window-management/multi-screen-fullscreen-companion.tentative.https.html [ Failure Pass ]
 
 # Gardener 2023-06-13
 crbug.com/1450287 [ Mac13-arm64 ] virtual/scalefactor200/external/wpt/largest-contentful-paint/multiple-redirects-TAO.html [ Failure Pass ]
@@ -7326,7 +7336,6 @@
 crbug.com/1499775 [ Chrome ] external/wpt/mathml/relations/html5-tree/tabindex-002.html [ Skip Timeout ]
 crbug.com/1499775 [ Chrome ] external/wpt/notifications/event-onclose.https.html [ Timeout ]
 crbug.com/1499775 [ Chrome ] external/wpt/notifications/event-onshow.https.html [ Timeout ]
-crbug.com/1499775 [ Chrome ] external/wpt/notifications/getnotifications-across-processes.https.window.html [ Timeout ]
 crbug.com/1499775 [ Chrome ] external/wpt/page-visibility/visibility-state-entry.tentative.html [ Skip Timeout ]
 crbug.com/1499775 [ Chrome ] external/wpt/performance-timeline/back-forward-cache-restoration.tentative.html [ Timeout ]
 crbug.com/1499775 [ Chrome ] external/wpt/permissions-policy/payment-extension-allowed-by-permissions-policy-attribute.https.sub.html [ Timeout ]
@@ -7339,7 +7348,6 @@
 crbug.com/1499775 [ Chrome ] external/wpt/screen-orientation/event-before-promise.html [ Timeout ]
 crbug.com/1499775 [ Chrome ] external/wpt/screen-orientation/fullscreen-interactions.html [ Timeout ]
 crbug.com/1499775 [ Chrome ] external/wpt/screen-orientation/lock-basic.html [ Timeout ]
-crbug.com/1499775 [ Chrome ] external/wpt/screen-orientation/lock-sandboxed-iframe.html [ Timeout ]
 crbug.com/1499775 [ Chrome ] external/wpt/screen-orientation/lock-unlock-check.html [ Timeout ]
 crbug.com/1499775 [ Chrome ] external/wpt/screen-orientation/nested-documents.html [ Timeout ]
 crbug.com/1499775 [ Chrome ] external/wpt/screen-orientation/onchange-event.html [ Timeout ]
@@ -7410,12 +7418,78 @@
 crbug.com/1499775 [ Chrome ] wpt_internal/soft-navigation-heuristics/browser-initiated-popstate.tentative.html [ Timeout ]
 crbug.com/1499775 [ Chrome ] wpt_internal/speech/scripted/speechrecognition-restart-onend.html [ Skip Timeout ]
 crbug.com/1499775 [ Chrome ] wpt_internal/storage-access-api/storage-access-origin-trial.sub.https.window.html [ Timeout ]
-crbug.com/1499775 [ Chrome ] wpt_internal/webmidi/loopback-receive.https.html [ Timeout ]
-crbug.com/1499775 [ Chrome ] wpt_internal/webmidi/loopback-with-timestamp.https.html [ Timeout ]
-crbug.com/1499775 [ Chrome ] wpt_internal/webmidi/requestmidiaccess-upgrade.https.html [ Timeout ]
-crbug.com/1499775 [ Chrome ] wpt_internal/websocket-cookies/third-party-cookie-blocked.https.html [ Failure ]  # Flaky output
 crbug.com/1499775 [ Chrome ] wpt_internal/webusb/usbDevice-iframe.https.html [ Timeout ]
 crbug.com/1499775 [ Chrome ] wpt_internal/webxr/ar/iframe-oopif.sub.https.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/css/css-inline/initial-letter/initial-letter-block-position-drop-under-ruby-tall.html [ Failure Pass ]
+crbug.com/1499775 [ Chrome ] external/wpt/css/css-overflow/incremental-scroll.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/css/css-scroll-anchoring/fullscreen-crash.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/css/css-shadow-parts/interaction-with-nested-pseudo-class.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/css/css-text-decor/invalidation/text-decoration-thickness.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/api/document-exit-fullscreen-nested-shadow-dom.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/api/document-exit-fullscreen-nested.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/api/document-exit-fullscreen-timing.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/api/document-exit-fullscreen-twice.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/api/document-exit-fullscreen.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/api/document-fullscreen-element.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/api/document-onfullscreenchange.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/api/element-ready-allowed.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/api/element-ready-check-allowed-cross-origin.sub.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/api/element-ready-check-containing-iframe.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/api/element-ready-check-fullscreen-element-sibling.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/api/element-ready-check-fullscreen-iframe-child.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/api/element-ready-check-iframe-child.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/api/element-request-fullscreen-after-error.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/api/element-request-fullscreen-and-exit-iframe.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/api/element-request-fullscreen-and-move-to-iframe.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/api/element-request-fullscreen-and-move.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/api/element-request-fullscreen-consume-user-activation.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/api/element-request-fullscreen-cross-origin.sub.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/api/element-request-fullscreen-namespaces.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/crashtests/content-visibility-crash.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/model/move-fullscreen-element.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/model/move-to-fullscreen-iframe.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/model/move-to-iframe.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/model/move-to-inactive-document.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/model/remove-child.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/model/remove-first.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/rendering/backdrop-iframe.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/rendering/backdrop-object.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/fullscreen/rendering/fullscreen-root-fills-page.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/html/semantics/forms/the-selectlist-element/selectlist-option-arbitrary-content-displayed.tentative.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/service-workers/cache-storage/crashtests/cache-response-clone.https.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/shadow-dom/crashtests/move-to-new-tree-1343016.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/signed-exchange/reporting/sxg-reporting-navigation-cert_fetch_error-downgraded.tentative.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/signed-exchange/reporting/sxg-reporting-navigation-cert_fetch_error.tentative.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/signed-exchange/reporting/sxg-reporting-navigation-cert_parse_error-downgraded.tentative.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/signed-exchange/reporting/sxg-reporting-navigation-cert_parse_error.tentative.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/signed-exchange/reporting/sxg-reporting-navigation-cert_verification_error-downgraded.tentative.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/signed-exchange/reporting/sxg-reporting-navigation-cert_verification_error.tentative.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/signed-exchange/reporting/sxg-reporting-navigation-invalid_integrity_header.tentative.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/signed-exchange/reporting/sxg-reporting-navigation-ok-no-referrer.tentative.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/signed-exchange/reporting/sxg-reporting-navigation-ok-origin-referrer.tentative.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/signed-exchange/reporting/sxg-reporting-navigation-ok.tentative.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/signed-exchange/reporting/sxg-reporting-navigation-signature_verification_error-downgraded.tentative.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/signed-exchange/reporting/sxg-reporting-navigation-signature_verification_error.tentative.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/signed-exchange/reporting/sxg-reporting-prefetch-cert_fetch_error-downgraded.tentative.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/signed-exchange/reporting/sxg-reporting-prefetch-cert_fetch_error.tentative.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/signed-exchange/reporting/sxg-reporting-prefetch-cert_parse_error-downgraded.tentative.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/signed-exchange/reporting/sxg-reporting-prefetch-cert_parse_error.tentative.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/signed-exchange/reporting/sxg-reporting-prefetch-cert_verification_error-downgraded.tentative.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/signed-exchange/reporting/sxg-reporting-prefetch-cert_verification_error.tentative.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/websockets/send-many-64K-messages-with-backpressure.any.html?wpt_flags=h2 [ Skip Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/websockets/send-many-64K-messages-with-backpressure.any.serviceworker.html?wpt_flags=h2 [ Skip Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/websockets/send-many-64K-messages-with-backpressure.any.worker.html?wpt_flags=h2 [ Skip Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/websockets/stream/tentative/backpressure-send.any.html?wpt_flags=h2 [ Skip Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/websockets/stream/tentative/backpressure-send.any.serviceworker.html?wpt_flags=h2 [ Skip Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/websockets/stream/tentative/backpressure-send.any.worker.html?wpt_flags=h2 [ Skip Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/window-management/multi-screen-fullscreen-companion.tentative.https.html [ Skip Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/window-management/multi-screen-fullscreen-enter.tentative.https.html [ Skip Timeout ]
+crbug.com/1499775 [ Chrome ] external/wpt/window-management/multi-screen-fullscreen-move.tentative.https.html [ Skip Timeout ]
+crbug.com/1499775 [ Chrome ] wpt_internal/css/css-fonts/variable-opsz-zoom-size-adjust.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] wpt_internal/css/css-fonts/variable-opsz-zoom.html [ Timeout ]
+crbug.com/1499775 [ Chrome ] wpt_internal/prerender/activate-from-iframe.html [ Skip Timeout ]
+crbug.com/1499775 [ Chrome ] wpt_internal/prerender/navigator-subapp.https.html [ Skip Timeout ]
+crbug.com/1499775 [ Chrome ] wpt_internal/prerender/restriction-pointer-lock.html [ Skip Timeout ]
 
 # Gardener 2023-10-17
 crbug.com/1493342 [ Mac10.15 ] external/wpt/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-video.html [ Failure ]
@@ -7446,12 +7520,3 @@
 # Gardener 2023-11-02
 crbug.com/1498203 external/wpt/fetch/fetch-later/send-on-discard.tentative.https.window.html [ Failure Pass ]
 crbug.com/1498203 virtual/keepalive-in-browser-migration/external/wpt/fetch/fetch-later/send-on-discard.tentative.https.window.html [ Failure Pass ]
-
-# Importer 2023-11-06
-crbug.com/626703 external/wpt/css/css-page/parsing/size-invalid.html [ Failure Pass ]
-crbug.com/626703 external/wpt/css/css-text/text-align/text-align-justify-tabs-001.html [ Failure Pass ]
-crbug.com/626703 external/wpt/css/css-text/text-align/text-align-justify-tabs-002.html [ Failure Pass ]
-crbug.com/626703 external/wpt/css/css-text/text-align/text-align-justify-tabs-003.html [ Failure Pass ]
-crbug.com/626703 external/wpt/css/css-text/text-align/text-align-justify-tabs-004.html [ Failure Pass ]
-crbug.com/626703 external/wpt/editing/run/formatblock.html?1-1000 [ Failure Pass ]
-crbug.com/626703 external/wpt/editing/run/formatblock.html?4001-last [ Failure Pass ]
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index 74bb3b0..d86d687 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -4568,6 +4568,13 @@
        {}
       ]
      ],
+     "insert-invalid-where-rule-crash.html": [
+      "752f7043b4fbd7b792ffc34826586db045b1cef8",
+      [
+       null,
+       {}
+      ]
+     ],
      "removerule-invalidation-crash.html": [
       "a83f43d5faf62338cfb442468a6e9e0e011c79f2",
       [
@@ -110435,6 +110442,32 @@
         {}
        ]
       ],
+      "content-visibility-vs-scrollIntoView-001.html": [
+       "0f874e660753ea36ba7234281757c3495bba798f",
+       [
+        null,
+        [
+         [
+          "/css/css-contain/content-visibility/content-visibility-vs-scrollIntoView-001-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "content-visibility-vs-scrollIntoView-002.html": [
+       "5358fc6db8ae79fb5eeca6e9adeaeb7a802e5492",
+       [
+        null,
+        [
+         [
+          "/css/css-contain/content-visibility/content-visibility-vs-scrollIntoView-002-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
       "content-visibility-with-popover-top-layer-000.html": [
        "fef4f5e5405e038aa10c1c0e21a71df6a82cd78f",
        [
@@ -167539,6 +167572,19 @@
        {}
       ]
      ],
+     "position-absolute-dynamic-relayout-004.html": [
+      "b94a8cdbfffe2df7f445d7a8d76b0b02ead826ec",
+      [
+       null,
+       [
+        [
+         "/css/reference/ref-filled-green-100px-square.xht",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "position-absolute-dynamic-static-position-flex.html": [
       "37e6fed3515fa56031fea43aa141cedea0ace117",
       [
@@ -193443,6 +193489,58 @@
         {}
        ]
       ],
+      "text-align-justify-tabs-001.html": [
+       "6905b4b601b719bf8b14bb8033fa81fbef644d21",
+       [
+        null,
+        [
+         [
+          "/css/css-text/text-align/reference/text-align-justify-tabs-001-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "text-align-justify-tabs-002.html": [
+       "473a960bdaa6aca9c8e9b18014a4783d71dde21e",
+       [
+        null,
+        [
+         [
+          "/css/css-text/text-align/reference/text-align-justify-tabs-002-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "text-align-justify-tabs-003.html": [
+       "f3fb0cf93b3fee03e4b78514e1411964640b6d88",
+       [
+        null,
+        [
+         [
+          "/css/css-text/text-align/reference/text-align-justify-tabs-002-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "text-align-justify-tabs-004.html": [
+       "689f6f6a698712b66bfa2fbb9ecc1d901062fe03",
+       [
+        null,
+        [
+         [
+          "/css/css-text/text-align/reference/text-align-justify-tabs-002-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
       "text-align-last-010.html": [
        "40d288ade328ea91c72d6c7abdff89f98c8139d4",
        [
@@ -292124,6 +292222,12 @@
      []
     ]
    },
+   "cookie-deprecation-label": {
+    "dummy.html": [
+     "f75136b522d932f90fb3416a956cbd9871deff45",
+     []
+    ]
+   },
    "cookie-store": {
     "DIR_METADATA": [
      "2d1e4e3e2f3bdb3cbc142d17a8ed3f5e08a34238",
@@ -303862,7 +303966,7 @@
      ],
      "parsing": {
       "color-computed-color-mix-function-expected.txt": [
-       "c67c1defa14f14fcf953e52f923b1d6a35da72b6",
+       "32cd314241f4c86477d3a8348fbca842417c42a7",
        []
       ],
       "opacity-valid-expected.txt": [
@@ -304791,6 +304895,14 @@
        "5e1e9bdde841828cbd4fc3d6cc165305361f4f36",
        []
       ],
+      "content-visibility-vs-scrollIntoView-001-ref.html": [
+       "897463844aa4c79a383b2130a1e1f5aea11eea33",
+       []
+      ],
+      "content-visibility-vs-scrollIntoView-002-ref.html": [
+       "417549e9195bbecc18ebf3bc10b0b3316e636680",
+       []
+      ],
       "content-visibility-with-popover-top-layer-and-auto-descendant-ref.html": [
        "211bb89a33eadb6f0f8b8b5703c39a7b1d6dc67f",
        []
@@ -327255,7 +327367,7 @@
       ]
      },
      "urange-parsing-expected.txt": [
-      "65e474c16e6cd2a5840b5d24dd71966e8959c4a1",
+      "0e312f02e449e98ca47581b5d15b3676605d080f",
       []
      ]
     },
@@ -329788,6 +329900,14 @@
         "e7148ece536ea8928219464581e22e598a73b11e",
         []
        ],
+       "text-align-justify-tabs-001-ref.html": [
+        "6f47afab8e6529288c8f6c2f6b0e232d31a57053",
+        []
+       ],
+       "text-align-justify-tabs-002-ref.html": [
+        "105f7aa2ef2be483e24954c75aae5b945bd86bf9",
+        []
+       ],
        "text-align-justifyall-ref-001.html": [
         "e9d071ee99333b001eb67be4621b45cd0b5c2a2e",
         []
@@ -339896,10 +340016,6 @@
       "8bcbf4110267dca94150e28c61fdb1783b73df08",
       []
      ],
-     "checkVisibility-expected.txt": [
-      "36867c5aeb84f1e5db0568e23e8cdad8d2234a4c",
-      []
-     ],
      "cssom-getBoundingClientRect-vertical-rl-ref.html": [
       "0b68c4f210c95dde58ffac2442472321ef6480a0",
       []
@@ -344251,7 +344367,7 @@
       []
      ],
      "formatblock.js": [
-      "6efd466d3822de83546df60c8b53ce6dd9884c63",
+      "bd559b3003686d79358b14e3d8389b18d3034d06",
       []
      ],
      "forwarddelete.js": [
@@ -344953,15 +345069,15 @@
       []
      ],
      "formatblock_2001-3000-expected.txt": [
-      "fc852cc1421be44fc65a6ad473590645dc56311d",
+      "59b88edb7530debebd5627e292054f95c63ca1a5",
       []
      ],
      "formatblock_3001-4000-expected.txt": [
-      "7717d2f2fb835bdc26126353ea2d37a7e16dc74a",
+      "6bca911f2ff04f5e639dfbeea254047d532e23cd",
       []
      ],
      "formatblock_4001-last-expected.txt": [
-      "f22a7688e2fdfc73aa5f60d52393c677319486fb",
+      "849dd5f2520531e90a13f447868686587c0dc66d",
       []
      ],
      "forwarddelete_1-1000-expected.txt": [
@@ -349866,7 +349982,7 @@
        []
       ],
       "preflight.py": [
-       "be3abdbb2a1850c6c68ed0064ee45645fa85496b",
+       "255bd56a33e73858498e02bb66e799b25b78a0ed",
        []
       ],
       "service-worker-bridge.html": [
@@ -349894,7 +350010,7 @@
        []
       ],
       "support.sub.js": [
-       "f8621338cc263c0621fdd49eb088cd61223d1348",
+       "3d71b2d298d8507a49856f174d7f8c715f9eaa3b",
        []
       ],
       "worker-blob-fetcher.html": [
@@ -350116,6 +350232,10 @@
       "83591131076b7b64ce9c0ee6d13a14474c718cab",
       []
      ],
+     "kanon-status-below-threshold.https.window-expected.txt": [
+      "89e64d0dde16b3e32e235a39669e7ca954a3aa67",
+      []
+     ],
      "resources": {
       "bidding-logic.sub.py": [
        "c0d6114ab2c6102ba545e92a969a1eecce696d85",
@@ -350134,7 +350254,7 @@
        []
       ],
       "fledge-util.sub.js": [
-       "4dd971d16ea8728a48d3149b42f18fc90aa7dbd6",
+       "b547c3c7d5286d0bf19060c651f45d315b48a2e1",
        []
       ],
       "fledge_http_server_util.py": [
@@ -350171,7 +350291,7 @@
       ]
      },
      "round-a-value.https.window-expected.txt": [
-      "77a8bb3943a0988a3ad1b5e4798610d180ad1016",
+      "ea45d0a01311017868c8bc366ca3587cc7a59f8d",
       []
      ]
     }
@@ -356713,7 +356833,7 @@
         []
        ],
        "text.yaml": [
-        "8bbc874f06f499ab1d9780114edb06d467ac9b4c",
+        "ca945c2953c70899c3946146570dd49231cd07b5",
         []
        ],
        "the-canvas-state.yaml": [
@@ -367506,6 +367626,10 @@
         "68d95fe240cc58c9d9b5e7ab1e9ec8b17c62305d",
         []
        ],
+       "input-checkbox-switch.tentative.window-expected.txt": [
+        "bfcd77e6f009c7f0d2974b8328301a9c65342670",
+        []
+       ],
        "utils.js": [
         "7a2fb77f105705b2ece7b7e495a3673f59faef94",
         []
@@ -369675,6 +369799,10 @@
      "086bb96e34a6e01452957f8ded5b19e41bb237c8",
      []
     ],
+    "roles-dynamic-switch.tentative.window-expected.txt": [
+     "815223e8adcf5f1190ee0aef3bdec840232705aa",
+     []
+    ],
     "roles-expected.txt": [
      "086bb96e34a6e01452957f8ded5b19e41bb237c8",
      []
@@ -369683,6 +369811,10 @@
      "086bb96e34a6e01452957f8ded5b19e41bb237c8",
      []
     ],
+    "roles.tentative-expected.txt": [
+     "086bb96e34a6e01452957f8ded5b19e41bb237c8",
+     []
+    ],
     "table-roles-expected.txt": [
      "086bb96e34a6e01452957f8ded5b19e41bb237c8",
      []
@@ -429659,7 +429791,7 @@
    },
    "cookie-deprecation-label": {
     "cookie-deprecation-label-detached-iframe.https.html": [
-     "9573dd2a4a14e9324c152292462390e2f6662fd0",
+     "8b63286b01266835ff2569752aa014f5711342d4",
      [
       null,
       {}
@@ -438701,6 +438833,13 @@
         {}
        ]
       ],
+      "content-visibility-vs-scrollIntoView-003.html": [
+       "685dba0b7b4387a797480e34a47a00a5279f116b",
+       [
+        null,
+        {}
+       ]
+      ],
       "content-visibility-with-popover-top-layer-006.html": [
        "fbe8b9fbb777b2fdd632ddc0f17e69fbfed06bd7",
        [
@@ -446387,7 +446526,7 @@
       ]
      ],
      "highlight-pseudo-parsing.html": [
-      "c6d999efdf74d6998fe36f6d365d2c33577dabf5",
+      "1c7de5bd28b4ca1a24e24248f40b3c4f9471376e",
       [
        null,
        {}
@@ -449356,6 +449495,13 @@
         null,
         {}
        ]
+      ],
+      "size-invalid.html": [
+       "6e7c4a222df82e7ebb989831c373d556905a5bc2",
+       [
+        null,
+        {}
+       ]
       ]
      }
     },
@@ -454774,7 +454920,7 @@
       ]
      ],
      "urange-parsing.html": [
-      "2d34e05a98ba895cd0c98415bed32f248b235187",
+      "d01f6a54c3fddbf2effa511918c21bbe2eabfe70",
       [
        null,
        {}
@@ -463436,7 +463582,7 @@
       ]
      ],
      "round-function.html": [
-      "bc8734b011a6e7c55e206e1bb13c40b0fc555958",
+      "d21f56d6c8a70b9f0c5e6ac0f88232467d1b8cd2",
       [
        null,
        {}
@@ -463570,6 +463716,13 @@
        {}
       ]
      ],
+     "viewport-units-extreme-scale.html": [
+      "95f0a23a94870a77e329f33991ccb8e04411586b",
+      [
+       null,
+       {}
+      ]
+     ],
      "viewport-units-invalidation.html": [
       "c7c980e04d85367ea7eae601abf29301cc3f3087",
       [
@@ -465578,6 +465731,13 @@
        {}
       ]
      ],
+     "invalid-pseudo-elements.html": [
+      "35a452654e0afcd633ebaa56402e5c6c9d8b9361",
+      [
+       null,
+       {}
+      ]
+     ],
      "medialist-interfaces-001.html": [
       "f436177fb8ec210d878418883d7876f64d1c45df",
       [
@@ -465896,7 +466056,7 @@
       ]
      ],
      "checkVisibility.html": [
-      "1d6ee35d771192d26867916bdf57797ebaf3e513",
+      "e77be7e9286be2f1cef1f11f2ea5129e0b1311be",
       [
        null,
        {}
@@ -507128,7 +507288,7 @@
       ]
      ],
      "iframe.tentative.https.window.js": [
-      "0c12970557d234093d77735dc2d422160c2da19f",
+      "bf16b6ca7e131d6c0021818fc780950117537039",
       [
        "fetch/private-network-access/iframe.tentative.https.window.html?include=from-local",
        {
@@ -509157,6 +509317,129 @@
        }
       ]
      ],
+     "component-auction.https.window.js": [
+      "cfaf174225185100227dcb6de568b5c26cb8a005",
+      [
+       "fledge/tentative/component-auction.https.window.html?1-5",
+       {
+        "script_metadata": [
+         [
+          "script",
+          "/resources/testdriver.js"
+         ],
+         [
+          "script",
+          "/common/utils.js"
+         ],
+         [
+          "script",
+          "/common/subset-tests.js"
+         ],
+         [
+          "script",
+          "resources/fledge-util.sub.js"
+         ],
+         [
+          "timeout",
+          "long"
+         ],
+         [
+          "variant",
+          "?1-5"
+         ],
+         [
+          "variant",
+          "?6-10"
+         ],
+         [
+          "variant",
+          "?11-last"
+         ]
+        ],
+        "timeout": "long"
+       }
+      ],
+      [
+       "fledge/tentative/component-auction.https.window.html?11-last",
+       {
+        "script_metadata": [
+         [
+          "script",
+          "/resources/testdriver.js"
+         ],
+         [
+          "script",
+          "/common/utils.js"
+         ],
+         [
+          "script",
+          "/common/subset-tests.js"
+         ],
+         [
+          "script",
+          "resources/fledge-util.sub.js"
+         ],
+         [
+          "timeout",
+          "long"
+         ],
+         [
+          "variant",
+          "?1-5"
+         ],
+         [
+          "variant",
+          "?6-10"
+         ],
+         [
+          "variant",
+          "?11-last"
+         ]
+        ],
+        "timeout": "long"
+       }
+      ],
+      [
+       "fledge/tentative/component-auction.https.window.html?6-10",
+       {
+        "script_metadata": [
+         [
+          "script",
+          "/resources/testdriver.js"
+         ],
+         [
+          "script",
+          "/common/utils.js"
+         ],
+         [
+          "script",
+          "/common/subset-tests.js"
+         ],
+         [
+          "script",
+          "resources/fledge-util.sub.js"
+         ],
+         [
+          "timeout",
+          "long"
+         ],
+         [
+          "variant",
+          "?1-5"
+         ],
+         [
+          "variant",
+          "?6-10"
+         ],
+         [
+          "variant",
+          "?11-last"
+         ]
+        ],
+        "timeout": "long"
+       }
+      ]
+     ],
      "cross-origin.https.window.js": [
       "788558e5cf364d2a3cc6b611d843ade2628821ff",
       [
@@ -509337,7 +509620,7 @@
       ]
      ],
      "currency.https.window.js": [
-      "3ae9ef5bfe908d067796a739c59777aea7f50dba",
+      "21b3f9af3a5a21be0d0c84ef0610a9db34c8a33d",
       [
        "fledge/tentative/currency.https.window.html?1-4",
        {
@@ -509368,14 +509651,26 @@
          ],
          [
           "variant",
-          "?5-last"
+          "?5-8"
+         ],
+         [
+          "variant",
+          "?9-12"
+         ],
+         [
+          "variant",
+          "?13-16"
+         ],
+         [
+          "variant",
+          "?17-last"
          ]
         ],
         "timeout": "long"
        }
       ],
       [
-       "fledge/tentative/currency.https.window.html?5-last",
+       "fledge/tentative/currency.https.window.html?13-16",
        {
         "script_metadata": [
          [
@@ -509404,7 +509699,163 @@
          ],
          [
           "variant",
-          "?5-last"
+          "?5-8"
+         ],
+         [
+          "variant",
+          "?9-12"
+         ],
+         [
+          "variant",
+          "?13-16"
+         ],
+         [
+          "variant",
+          "?17-last"
+         ]
+        ],
+        "timeout": "long"
+       }
+      ],
+      [
+       "fledge/tentative/currency.https.window.html?17-last",
+       {
+        "script_metadata": [
+         [
+          "script",
+          "/resources/testdriver.js"
+         ],
+         [
+          "script",
+          "/common/utils.js"
+         ],
+         [
+          "script",
+          "resources/fledge-util.sub.js"
+         ],
+         [
+          "script",
+          "/common/subset-tests.js"
+         ],
+         [
+          "timeout",
+          "long"
+         ],
+         [
+          "variant",
+          "?1-4"
+         ],
+         [
+          "variant",
+          "?5-8"
+         ],
+         [
+          "variant",
+          "?9-12"
+         ],
+         [
+          "variant",
+          "?13-16"
+         ],
+         [
+          "variant",
+          "?17-last"
+         ]
+        ],
+        "timeout": "long"
+       }
+      ],
+      [
+       "fledge/tentative/currency.https.window.html?5-8",
+       {
+        "script_metadata": [
+         [
+          "script",
+          "/resources/testdriver.js"
+         ],
+         [
+          "script",
+          "/common/utils.js"
+         ],
+         [
+          "script",
+          "resources/fledge-util.sub.js"
+         ],
+         [
+          "script",
+          "/common/subset-tests.js"
+         ],
+         [
+          "timeout",
+          "long"
+         ],
+         [
+          "variant",
+          "?1-4"
+         ],
+         [
+          "variant",
+          "?5-8"
+         ],
+         [
+          "variant",
+          "?9-12"
+         ],
+         [
+          "variant",
+          "?13-16"
+         ],
+         [
+          "variant",
+          "?17-last"
+         ]
+        ],
+        "timeout": "long"
+       }
+      ],
+      [
+       "fledge/tentative/currency.https.window.html?9-12",
+       {
+        "script_metadata": [
+         [
+          "script",
+          "/resources/testdriver.js"
+         ],
+         [
+          "script",
+          "/common/utils.js"
+         ],
+         [
+          "script",
+          "resources/fledge-util.sub.js"
+         ],
+         [
+          "script",
+          "/common/subset-tests.js"
+         ],
+         [
+          "timeout",
+          "long"
+         ],
+         [
+          "variant",
+          "?1-4"
+         ],
+         [
+          "variant",
+          "?5-8"
+         ],
+         [
+          "variant",
+          "?9-12"
+         ],
+         [
+          "variant",
+          "?13-16"
+         ],
+         [
+          "variant",
+          "?17-last"
          ]
         ],
         "timeout": "long"
@@ -510161,6 +510612,58 @@
        }
       ]
      ],
+     "kanon-status-below-threshold.https.window.js": [
+      "4eac4a8e917b17a7e6d43b60261e5abdecad76e5",
+      [
+       "fledge/tentative/kanon-status-below-threshold.https.window.html",
+       {
+        "script_metadata": [
+         [
+          "script",
+          "/resources/testdriver.js"
+         ],
+         [
+          "script",
+          "/common/utils.js"
+         ],
+         [
+          "script",
+          "resources/fledge-util.sub.js"
+         ],
+         [
+          "script",
+          "/common/subset-tests.js"
+         ]
+        ]
+       }
+      ]
+     ],
+     "kanon-status-not-calculated.https.window.js": [
+      "a3ac19bd85e5f2abcedba9c973177bcf602d4cb2",
+      [
+       "fledge/tentative/kanon-status-not-calculated.https.window.html",
+       {
+        "script_metadata": [
+         [
+          "script",
+          "/resources/testdriver.js"
+         ],
+         [
+          "script",
+          "/common/utils.js"
+         ],
+         [
+          "script",
+          "resources/fledge-util.sub.js"
+         ],
+         [
+          "script",
+          "/common/subset-tests.js"
+         ]
+        ]
+       }
+      ]
+     ],
      "network.https.window.js": [
       "fe287767c8d051328b82e7501a64f0ad86cc0505",
       [
@@ -530452,7 +530955,7 @@
         ]
        ],
        "2d.text.drawing.style.letterSpacing.change.font.html": [
-        "74774b5cce5eb6e34708af22d96ec592fa640e0a",
+        "daff0cf9d6423e4ae6c54a86cb41bd26c4ac22a1",
         [
          null,
          {}
@@ -543577,14 +544080,14 @@
         ]
        ],
        "2d.text.drawing.style.letterSpacing.change.font.html": [
-        "636f7199cb19ccf55bc83996d55adbed9ca53372",
+        "f8b453418c19dc6a643a82a769e75f8c722863f9",
         [
          null,
          {}
         ]
        ],
        "2d.text.drawing.style.letterSpacing.change.font.worker.js": [
-        "22fb04f62f921dcafc3457080fa378551a3f9960",
+        "510845c885aea568087632d9fb090ca81ca20dbd",
         [
          "html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.change.font.worker.html",
          {}
@@ -587990,7 +588493,7 @@
      ]
     ],
     "navigation-id-initial-load.tentative.html": [
-     "93ddcff062e726ea60a4f6041f6a6bfb23f6fc72",
+     "b996f0f117922d5908d235e7ebea5d105aae1b02",
      [
       null,
       {
@@ -645084,7 +645587,7 @@
      ]
     ],
     "full-cycle-test.https.any.js": [
-     "d2e4ad94ac0a34597a7acfbd4ad56fedb1c2275e",
+     "b7d5f7ea658fb6440ac253b9276110f97640131d",
      [
       "webcodecs/full-cycle-test.https.any.html?av1",
       {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-vs-scrollIntoView-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-vs-scrollIntoView-001-ref.html
new file mode 100644
index 0000000..8974638
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-vs-scrollIntoView-001-ref.html
@@ -0,0 +1,41 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Nested CSS Content Visibility: auto + scrollIntoView</title>
+<link rel="author" title="Cathie Chen" href="mailto:cathiechen@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
+<meta name="assert" content="Test if target scrollIntoView is visible when it is inside a nested content-visibility: auto">
+
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+
+    .child {
+        height: 40000px;
+        position: relative;
+    }
+
+    #target {
+        position: absolute;
+        bottom: 0;
+    }
+
+    .before_target {
+        height: 40000px;
+    }
+</style>
+
+<div id=e1 class="before_target"></div>
+<div id=e2 class="before_target"></div>
+<div id=e3 class="before_target"></div>
+<div id=e4 class="before_target"></div>
+<div id=e5 class=child>
+    <div id=target>PASS</div>
+</div>
+
+<script>
+    window.onload = () => {
+        target.scrollIntoView();
+        requestAnimationFrame(takeScreenshot);
+    }
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-vs-scrollIntoView-001.html b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-vs-scrollIntoView-001.html
new file mode 100644
index 0000000..0f874e66
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-vs-scrollIntoView-001.html
@@ -0,0 +1,58 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>Nested CSS Content Visibility: auto + scrollIntoView</title>
+<link rel="author" title="Cathie Chen" href="mailto:cathiechen@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
+<link rel="match" href="content-visibility-vs-scrollIntoView-001-ref.html">
+<meta name="assert"
+    content="Test if target scrollIntoView is visible when it is inside a nested content-visibility: auto">
+
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+    .auto {
+        content-visibility: auto;
+        contain-intrinsic-size: auto 1px auto 10000px;
+    }
+
+    .child {
+        height: 40000px;
+        position: relative;
+    }
+
+    #target {
+        position: absolute;
+        bottom: 0;
+    }
+
+    .before_target {
+        height: 40000px;
+    }
+</style>
+
+<div id=e1 class="auto before_target"></div>
+<div id=e2 class="auto before_target"></div>
+<div id=e3 class=auto>
+    <div class=auto>
+        <div class=child></div>
+        <div class=auto>
+            <div class=child></div>
+            <div class=auto>
+                <div class=child>
+                    <div id=target>PASS</div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+<script>
+    function runTest() {
+        target.scrollIntoView();
+        // Double rAF to ensure that rendering has "settled".
+        requestAnimationFrame(() => requestAnimationFrame(takeScreenshot));
+    }
+
+    window.onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest));
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-vs-scrollIntoView-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-vs-scrollIntoView-002-ref.html
new file mode 100644
index 0000000..417549e9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-vs-scrollIntoView-002-ref.html
@@ -0,0 +1,59 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>CSS Content Visibility: auto + overflow clip + scrollIntoView</title>
+<link rel="author" title="Cathie Chen" href="mailto:cathiechen@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
+<meta name="assert"
+    content="Test if target scrollIntoView is hidden when it is inside the overflow area of a content-visibility: auto which is not relevent content">
+
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+    .auto {
+        content-visibility: auto;
+        contain-intrinsic-size: auto 1px auto 10000px;
+    }
+
+    .child {
+        height: 40000px;
+        position: relative;
+    }
+
+    #target {
+        position: absolute;
+        bottom: 0;
+    }
+
+    .before_target {
+        height: 40000px;
+    }
+
+    #overflow_clip {
+        overflow: clip;
+        height: 20000px;
+    }
+</style>
+
+<div id=e1 class="auto before_target"></div>
+<div id=e2 class="auto before_target"></div>
+<div id=e3 class="auto">
+    <div id="overflow_clip">
+        <div class=child>
+            <div id=target>PASS</div>
+        </div>
+    </div>
+</div>
+<div id=e4 class=auto>
+    <div class=child></div>
+</div>
+
+
+<script>
+    function runTest() {
+        target.scrollIntoView();
+        requestAnimationFrame(() => requestAnimationFrame(takeScreenshot));
+    }
+
+    window.onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest));
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-vs-scrollIntoView-002.html b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-vs-scrollIntoView-002.html
new file mode 100644
index 0000000..5358fc6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-vs-scrollIntoView-002.html
@@ -0,0 +1,63 @@
+<!doctype HTML>
+<html class="reftest-wait">
+<meta charset="utf8">
+<title>CSS Content Visibility: auto + overflow clip + scrollIntoView</title>
+<link rel="author" title="Cathie Chen" href="mailto:cathiechen@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
+<link rel="match" href="content-visibility-vs-scrollIntoView-002-ref.html">
+<meta name="assert"
+    content="content-visibility: auto element not relevent to user should be hidden even after calling scrollIntoView of its descendant">
+
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+    .auto {
+        content-visibility: auto;
+        contain-intrinsic-size: auto 1px auto 10000px;
+    }
+
+    .child {
+        height: 40000px;
+        position: relative;
+    }
+
+    #target {
+        position: absolute;
+        bottom: 0;
+    }
+
+    .before_target {
+        height: 40000px;
+    }
+
+    #overflow_clip {
+        overflow: clip;
+        height: 20000px;
+    }
+</style>
+
+<div id=e1 class="auto before_target"></div>
+<div id=e2 class="auto before_target"></div>
+<div id=e3 class="auto">
+    <div id="overflow_clip">
+        <div class=child>
+            <div id=target>PASS</div>
+        </div>
+    </div>
+</div>
+<div id=e4 class=auto>
+    <div class=child></div>
+</div>
+
+<script>
+    function runTest() {
+        target.scrollIntoView();
+        requestAnimationFrame(() => requestAnimationFrame(() => {
+            // Remove the fixed value of height, so that the computed height would be 40000px.
+            // e3 should be hidden now, "PASS" should not show up.
+            overflow_clip.style.height = "auto";
+            requestAnimationFrame(() => requestAnimationFrame(takeScreenshot));
+        }));
+    }
+    window.onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest));
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-vs-scrollIntoView-003.html b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-vs-scrollIntoView-003.html
new file mode 100644
index 0000000..685dba0b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-vs-scrollIntoView-003.html
@@ -0,0 +1,81 @@
+<!doctype HTML>
+<html>
+<meta charset="utf8">
+<title>CSS Content Visibility: auto + overflow clip + scrollIntoView, ContentVisibilityAutoStateChange fires twice</title>
+<link rel="author" title="Cathie Chen" href="mailto:cathiechen@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-contain/#content-visibility">
+<meta name="assert"
+    content="If content-visibility: auto element is not relevent to user after calling scrollIntoView of its descendant, contentvisibilityautostatechange twice">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+    .auto {
+        content-visibility: auto;
+        contain-intrinsic-size: auto 1px auto 10000px;
+    }
+
+    .child {
+        height: 40000px;
+        position: relative;
+    }
+
+    #target {
+        position: absolute;
+        bottom: 0;
+    }
+
+    .before_target {
+        height: 40000px;
+    }
+
+    #overflow_clip {
+        overflow: clip;
+        height: 20000px;
+    }
+</style>
+
+<div id=e1 class="auto before_target"></div>
+<div id=e2 class="auto before_target"></div>
+<div id=e3 class="auto">
+    <div id="overflow_clip">
+        <div class=child>
+            <div id=target>PASS</div>
+        </div>
+    </div>
+</div>
+<div id=e4 class=auto>
+    <div class=child></div>
+</div>
+
+<script>
+promise_test(t => new Promise(async (resolve, reject) => {
+    await new Promise((waited, _) => {
+        requestAnimationFrame(() => requestAnimationFrame(waited));
+    });
+
+    function waitForEvent() {
+        return new Promise(resolve => e3.addEventListener('contentvisibilityautostatechange', resolve));
+    }
+
+    var eventCounter = 0;
+    function eventHandler(e) {
+        eventCounter++;
+        if (eventCounter == 1) {
+            assert_equals(e.skipped, false, "the first event should be generated by visible");
+        } else if (eventCounter == 2) {
+            assert_equals(e.skipped, true, "the second event should be generated by hidden");
+        }
+    }
+
+    e3.addEventListener("contentvisibilityautostatechange", eventHandler);
+    target.scrollIntoView();
+    await waitForEvent();
+    await waitForEvent();
+    requestAnimationFrame(() => requestAnimationFrame(() => {
+        assert_equals(eventCounter, 2, "There should be two contentvisibilityautostatechange events.");
+        resolve();
+    }));
+}), "ContentVisibilityAutoStateChange fires twice when `scrollIntoView` a descendant of `content-visibility:auto` which is hidden after scrolling");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-highlight-api/highlight-pseudo-parsing.html b/third_party/blink/web_tests/external/wpt/css/css-highlight-api/highlight-pseudo-parsing.html
index c6d999efd..1c7de5bd 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-highlight-api/highlight-pseudo-parsing.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-highlight-api/highlight-pseudo-parsing.html
@@ -7,11 +7,12 @@
 <script src="/css/support/parsing-testcommon.js"></script>
 <script>
   const pseudo = "::highlight(foo)";
-  test_valid_selector(`${pseudo}`);
+  test_valid_selector(pseudo);
   test_valid_selector(`.a${pseudo}`);
   test_valid_selector(`div ${pseudo}`);
   test_valid_selector(`::part(my-part)${pseudo}`);
 
+  test_invalid_selector("::highlight");
   test_invalid_selector(`::before${pseudo}`);
   test_invalid_selector(`${pseudo}.a`);
   test_invalid_selector(`${pseudo} div`);
diff --git a/third_party/blink/web_tests/external/wpt/css/css-page/parsing/size-invalid-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-page/parsing/size-invalid-expected.txt
new file mode 100644
index 0000000..46b13aa
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-page/parsing/size-invalid-expected.txt
@@ -0,0 +1,31 @@
+This is a testharness.js-based test.
+[FAIL] e.style['size'] = "initial" should not set the property value
+  assert_equals: expected "" but got "initial"
+[FAIL] e.style['size'] = "inherit" should not set the property value
+  assert_equals: expected "" but got "inherit"
+[FAIL] e.style['size'] = "revert" should not set the property value
+  assert_equals: expected "" but got "revert"
+[FAIL] e.style['size'] = "revert-layer" should not set the property value
+  assert_equals: expected "" but got "revert-layer"
+[FAIL] e.style['size'] = "unset" should not set the property value
+  assert_equals: expected "" but got "unset"
+[FAIL] e.style['size'] = "640px 480px" should not set the property value
+  assert_equals: expected "" but got "640px 480px"
+[FAIL] e.style['size'] = "8.5in 11in" should not set the property value
+  assert_equals: expected "" but got "8.5in 11in"
+[FAIL] e.style['size'] = "a4" should not set the property value
+  assert_equals: expected "" but got "a4"
+[FAIL] e.style['size'] = "3in 10in" should not set the property value
+  assert_equals: expected "" but got "3in 10in"
+[FAIL] e.style['size'] = "jis-b5" should not set the property value
+  assert_equals: expected "" but got "jis-b5"
+[FAIL] e.style['size'] = "auto" should not set the property value
+  assert_equals: expected "" but got "auto"
+[FAIL] e.style['size'] = "landscape" should not set the property value
+  assert_equals: expected "" but got "landscape"
+[FAIL] e.style['size'] = "letter" should not set the property value
+  assert_equals: expected "" but got "letter"
+[FAIL] e.style['size'] = "legal landscape" should not set the property value
+  assert_equals: expected "" but got "legal landscape"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-page/parsing/size-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-page/parsing/size-invalid.html
new file mode 100644
index 0000000..6e7c4a2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-page/parsing/size-invalid.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
+<link rel="help" href="https://drafts.csswg.org/css-page-3/#page-orientation-prop">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+<script>
+  // size is not a property, but a descriptor. test_invalid_value() tries to specify
+  // it on an element, and this should fail, even when using a valid
+  // value. size is only valid as a descriptor inside an @page rule.
+  test_invalid_value("size", "initial");
+  test_invalid_value("size", "inherit");
+  test_invalid_value("size", "revert");
+  test_invalid_value("size", "revert-layer");
+  test_invalid_value("size", "unset");
+  test_invalid_value("size", "640px 480px");
+  test_invalid_value("size", "8.5in 11in");
+  test_invalid_value("size", "a4");
+  test_invalid_value("size", "3in 10in");
+  test_invalid_value("size", "jis-b5");
+  test_invalid_value("size", "auto");
+  test_invalid_value("size", "landscape");
+  test_invalid_value("size", "letter");
+  test_invalid_value("size", "legal landscape");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-align/reference/text-align-justify-tabs-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/reference/text-align-justify-tabs-001-ref.html
new file mode 100644
index 0000000..6f47afab
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/reference/text-align-justify-tabs-001-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>text-align: justify and preserved tabs - reference</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+
+<style>
+div {
+  font: 25px Ahem, monospace;
+  width: 30ch;
+  white-space: pre-wrap;
+  tab-size: 8;
+  border: 1px solid gray;
+  padding: 2px;
+  margin: 2px;
+}
+</style>
+</head>
+
+<body>
+<p>The layout in the two boxes should be the same:</p>
+<div>a b c&#9;tab 1&#9;tab 2&#9;jklmnop</div>
+<div>a b c&#9;tab 1&#9;tab 2&#9;jklmnop</div>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-align/reference/text-align-justify-tabs-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/reference/text-align-justify-tabs-002-ref.html
new file mode 100644
index 0000000..105f7aa
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/reference/text-align-justify-tabs-002-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>text-align: justify and preserved tabs - reference</title>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+
+<style>
+div {
+  font: 25px Ahem, monospace;
+  width: 30ch;
+  white-space: pre-wrap;
+  tab-size: 8;
+  border: 1px solid gray;
+  padding: 2px;
+  margin: 2px;
+}
+</style>
+</head>
+
+<body>
+<p>The layout in the two boxes should be the same:</p>
+<div>a b c&#9;tab 1&#9;tab  2  jklmno<br>pqrs</div>
+<div>a b c&#9;tab 1&#9;tab  2  jklmno<br>pqrs</div>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-justify-tabs-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-justify-tabs-001.html
new file mode 100644
index 0000000..6905b4b6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-justify-tabs-001.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>text-align: justify and preserved tabs</title>
+<link rel='match' href='reference/text-align-justify-tabs-001-ref.html'>
+<link rel='author' title='Jonathan Kew' href='mailto:jkew@mozilla.com'>
+<link rel='help' href='https://www.w3.org/TR/css-text-4/#text-align-property'>
+<meta name="assert" content="If an element’s white space is not collapsible ...
+ensure that tab stops continue to line up as required by the white space processing rules.">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+
+<style>
+div {
+  font: 25px Ahem, monospace;
+  width: 30ch;
+  white-space: pre-wrap;
+  tab-size: 8;
+  border: 1px solid gray;
+  padding: 2px;
+  margin: 2px;
+}
+.test {
+  text-align: justify;
+}
+</style>
+</head>
+
+<body>
+<p>The layout in the two boxes should be the same:</p>
+<div>a b c&#9;tab 1&#9;tab 2&#9;jklmnop</div>
+<div class=test>a b c&#9;tab 1&#9;tab 2&#9;jklmnop</div>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-justify-tabs-002.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-justify-tabs-002.html
new file mode 100644
index 0000000..473a960
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-justify-tabs-002.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>text-align: justify and preserved tabs</title>
+<link rel='match' href='reference/text-align-justify-tabs-002-ref.html'>
+<link rel='author' title='Jonathan Kew' href='mailto:jkew@mozilla.com'>
+<link rel='help' href='https://www.w3.org/TR/css-text-4/#text-align-property'>
+<meta name="assert" content="If an element’s white space is not collapsible ...
+ensure that tab stops continue to line up as required by the white space processing rules.">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+
+<style>
+div {
+  font: 25px Ahem, monospace;
+  width: 30ch;
+  white-space: pre-wrap;
+  tab-size: 8;
+  border: 1px solid gray;
+  padding: 2px;
+  margin: 2px;
+}
+.test {
+  text-align: justify;
+}
+</style>
+</head>
+
+<body>
+<p>The layout in the two boxes should be the same:</p>
+<div>a b c&#9;tab 1&#9;tab  2  jklmno<br>pqrs</div>
+<div class=test>a b c&#9;tab 1&#9;tab 2 jklmno pqrs</div>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-justify-tabs-003.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-justify-tabs-003.html
new file mode 100644
index 0000000..f3fb0cf9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-justify-tabs-003.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>text-align: justify and preserved tabs</title>
+<link rel='match' href='reference/text-align-justify-tabs-002-ref.html'>
+<link rel='author' title='Jonathan Kew' href='mailto:jkew@mozilla.com'>
+<link rel='help' href='https://www.w3.org/TR/css-text-4/#text-align-property'>
+<meta name="assert" content="If an element’s white space is not collapsible ...
+ensure that tab stops continue to line up as required by the white space processing rules.">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+
+<style>
+div {
+  font: 25px Ahem, monospace;
+  width: 30ch;
+  white-space: pre-wrap;
+  tab-size: 8;
+  border: 1px solid gray;
+  padding: 2px;
+  margin: 2px;
+}
+.test {
+  text-align: justify;
+}
+</style>
+</head>
+
+<body>
+<p>The layout in the two boxes should be the same:</p>
+<div>a b c&#9;tab 1&#9;tab  2  jklmno<br>pqrs</div>
+<div class=test>a b c<b>&#9;</b>tab 1<b>&#9;</b>tab 2 jklmno pqrs</div>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-justify-tabs-004.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-justify-tabs-004.html
new file mode 100644
index 0000000..689f6f6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-justify-tabs-004.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>text-align: justify and preserved tabs</title>
+<link rel='match' href='reference/text-align-justify-tabs-002-ref.html'>
+<link rel='author' title='Jonathan Kew' href='mailto:jkew@mozilla.com'>
+<link rel='help' href='https://www.w3.org/TR/css-text-4/#text-align-property'>
+<meta name="assert" content="If an element’s white space is not collapsible ...
+ensure that tab stops continue to line up as required by the white space processing rules.">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+
+<style>
+div {
+  font: 25px Ahem, monospace;
+  width: 30ch;
+  white-space: pre-wrap;
+  tab-size: 8;
+  border: 1px solid gray;
+  padding: 2px;
+  margin: 2px;
+}
+.test {
+  text-align: justify;
+}
+</style>
+</head>
+
+<body>
+<p>The layout in the two boxes should be the same:</p>
+<div>a b c&#9;tab 1&#9;tab  2  jklmno<br>pqrs</div>
+<div class=test>a b c&#9;<span><span>tab 1<b>&#9;</b>tab 2</span> jklmno</span> pqrs</div>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/round-function.html b/third_party/blink/web_tests/external/wpt/css/css-values/round-function.html
index bc8734b..d21f56d 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-values/round-function.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-values/round-function.html
@@ -58,6 +58,59 @@
 test_math_used("round(-13px, -10px)", "-10px");
 test_math_used("round(-18px, -10px)", "-20px");
 
+// Test with value that is an exact multiple of step
+test_math_used("round(10px, 5px)", "10px");
+test_math_used("round(nearest, 10px, 5px)", "10px");
+test_math_used("round(down, 10px, 5px)", "10px");
+test_math_used("round(up, 10px, 5px)", "10px");
+test_math_used("round(to-zero, 10px, 5px)", "10px");
+
+test_math_used("round(-10px, 5px)", "-10px");
+test_math_used("round(nearest, -10px, 5px)", "-10px");
+test_math_used("round(down, -10px, 5px)", "-10px");
+test_math_used("round(up, -10px, 5px)", "-10px");
+test_math_used("round(to-zero, -10px, 5px)", "-10px");
+
+// Test negation of the round operation
+test_math_used("calc(0px - round(23px, 10px))", "-20px");
+test_math_used("calc(0px - round(18px, 10px))", "-20px");
+test_math_used("calc(0px - round(15px, 10px))", "-20px");
+test_math_used("calc(0px - round(13px, 10px))", "-10px");
+test_math_used("calc(0px - round(-13px, 10px))", "10px");
+test_math_used("calc(0px - round(-18px, 10px))", "20px");
+
+// Test negation of nearest
+test_math_used("calc(0px - round(nearest, 23px, 10px))", "-20px");
+test_math_used("calc(0px - round(nearest, 18px, 10px))", "-20px");
+test_math_used("calc(0px - round(nearest, 15px, 10px))", "-20px");
+test_math_used("calc(0px - round(nearest, 13px, 10px))", "-10px");
+test_math_used("calc(0px - round(nearest, -13px, 10px))", "10px");
+test_math_used("calc(0px - round(nearest, -18px, 10px))", "20px");
+
+// Test negation of down
+test_math_used("calc(0px - round(down, 23px, 10px))", "-20px");
+test_math_used("calc(0px - round(down, 18px, 10px))", "-10px");
+test_math_used("calc(0px - round(down, 15px, 10px))", "-10px");
+test_math_used("calc(0px - round(down, 13px, 10px))", "-10px");
+test_math_used("calc(0px - round(down, -13px, 10px))", "20px");
+test_math_used("calc(0px - round(down, -18px, 10px))", "20px");
+
+// Test negation of up
+test_math_used("calc(0px - round(up, 23px, 10px))", "-30px");
+test_math_used("calc(0px - round(up, 18px, 10px))", "-20px");
+test_math_used("calc(0px - round(up, 15px, 10px))", "-20px");
+test_math_used("calc(0px - round(up, 13px, 10px))", "-20px");
+test_math_used("calc(0px - round(up, -13px, 10px))", "10px");
+test_math_used("calc(0px - round(up, -18px, 10px))", "10px");
+
+// Test negation of to-zero
+test_math_used("calc(0px - round(to-zero, 23px, 10px))", "-20px");
+test_math_used("calc(0px - round(to-zero, 18px, 10px))", "-10px");
+test_math_used("calc(0px - round(to-zero, 15px, 10px))", "-10px");
+test_math_used("calc(0px - round(to-zero, 13px, 10px))", "-10px");
+test_math_used("calc(0px - round(to-zero, -13px, 10px))", "10px");
+test_math_used("calc(0px - round(to-zero, -18px, 10px))", "10px");
+
 // Extreme cases:
 
 // 0 step is NaN
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/viewport-units-extreme-scale.html b/third_party/blink/web_tests/external/wpt/css/css-values/viewport-units-extreme-scale.html
new file mode 100644
index 0000000..95f0a23
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-values/viewport-units-extreme-scale.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<title>Scaling with viewport units</title>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#viewport-relative-lengths">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1860338">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<iframe id=iframe width=640 height=480></iframe>
+
+<script>
+
+const doc = iframe.contentDocument;
+const win = iframe.contentWindow;
+
+function test_computed_value(value, expected) {
+  test((t) => {
+    t.add_cleanup(() => { doc.body.innerHTML = ''; });
+    doc.body.innerHTML = `
+      <!doctype html>
+      <style>
+        * { margin: 0; }
+        body { height: 100%; }
+        div { height: ${value}; }
+      </style>
+      <div></div>
+    `;
+    let div = doc.querySelector('div');
+    assert_equals(win.getComputedStyle(div).height, expected);
+  }, `${value} computes to ${expected}`);
+}
+
+// Check the basic units are as expected
+test_computed_value('100vw', '640px');
+test_computed_value('100vh', '480px');
+
+// Try some calculations involving extreme scaling
+test_computed_value('calc((1vw - 6.3999px) * 10000000)', '1000px');
+test_computed_value('calc((100vh - 479px) * 60000)', '60000px');
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom/change-rule-with-layers-crash.html b/third_party/blink/web_tests/external/wpt/css/cssom/change-rule-with-layers-crash.html
new file mode 100644
index 0000000..63e8ec5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/cssom/change-rule-with-layers-crash.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>CSSOM Test: Chrome crash when modifying rules with @layer</title>
+<link rel="help" href="https://crbug.com/1499277">
+<link rel="author" title="Steinar H. Gunderson" href="mailto:sesse@chromium.org">
+<style id="s">
+.x {
+  transition: color 0.5s;
+  @layer warning {
+    :first-child { }
+    :last-child { }
+  }
+}
+</style>
+<p>Test passes if it does not crash.</p>
+<script>
+document.body.offsetTop;
+s.sheet.cssRules[0].style.transitionDuration = '1s';
+</script>
+
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom/invalid-pseudo-elements.html b/third_party/blink/web_tests/external/wpt/css/cssom/invalid-pseudo-elements.html
new file mode 100644
index 0000000..35a4526
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/cssom/invalid-pseudo-elements.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSSOM: Test that rules with invalid pseudo elements are not found</title>
+<link rel="help" href="https://drafts.csswg.org/cssom/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+    ::part {}
+    ::slotted {}
+    ::highlight {}
+</style>
+<script>
+    test(() => {
+        assert_equals(document.styleSheets[0].cssRules[0]?.selectorText, undefined, "No associated selectorText");
+        assert_equals(document.styleSheets[0].cssRules[0], undefined, "No invalid pseudo element rule should be found");
+    });
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/editing/data/formatblock.js b/third_party/blink/web_tests/external/wpt/editing/data/formatblock.js
index 6efd466..bd559b30 100644
--- a/third_party/blink/web_tests/external/wpt/editing/data/formatblock.js
+++ b/third_party/blink/web_tests/external/wpt/editing/data/formatblock.js
@@ -239,12 +239,12 @@
     [["defaultparagraphseparator","div"],["formatblock","<div>"]],
     "<div>[foo</div><div>bar]</div>",
     [true,true],
-    {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"dl",false,false,"div"]}],
+    {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[false,false,"dl",false,false,"div"]}],
 ["<dl><dt>[foo<dd>bar]</dl>",
     [["defaultparagraphseparator","p"],["formatblock","<div>"]],
     "<div>[foo</div><div>bar]</div>",
     [true,true],
-    {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"dl",false,false,"div"]}],
+    {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[false,false,"dl",false,false,"div"]}],
 ["<ol><li>[foobar]</ol>",
     [["defaultparagraphseparator","div"],["formatblock","<div>"]],
     "<ol><li><div>[foobar]</div></li></ol>",
@@ -1735,12 +1735,12 @@
     [["defaultparagraphseparator","div"],["formatblock","<h1>"]],
     "<h1>[foo<br>bar]</h1>",
     [true,true],
-    {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"p",false,false,"h1"]}],
+    {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"",false,false,"h1"]}],
 ["<p>[foo</p>bar]",
     [["defaultparagraphseparator","p"],["formatblock","<h1>"]],
     "<h1>[foo<br>bar]</h1>",
     [true,true],
-    {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"p",false,false,"h1"]}],
+    {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"",false,false,"h1"]}],
 ["[foo<p>bar]</p>",
     [["defaultparagraphseparator","div"],["formatblock","<h1>"]],
     "<h1>[foo<br>bar]</h1>",
@@ -1805,32 +1805,32 @@
     [["defaultparagraphseparator","div"],["formatblock","<div>"]],
     "<div>[foo</div><div>bar]</div>",
     [true,true],
-    {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"p",false,false,"div"]}],
+    {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"",false,false,"div"]}],
 ["<p>[foo<h1>bar]</h1>",
     [["defaultparagraphseparator","p"],["formatblock","<div>"]],
     "<div>[foo</div><div>bar]</div>",
     [true,true],
-    {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"p",false,false,"div"]}],
+    {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"",false,false,"div"]}],
 ["<h1>[foo</h1><h2>bar]</h2>",
     [["defaultparagraphseparator","div"],["formatblock","<div>"]],
     "<div>[foo</div><div>bar]</div>",
     [true,true],
-    {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"h1",false,false,"div"]}],
+    {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"",false,false,"div"]}],
 ["<h1>[foo</h1><h2>bar]</h2>",
     [["defaultparagraphseparator","p"],["formatblock","<div>"]],
     "<div>[foo</div><div>bar]</div>",
     [true,true],
-    {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"h1",false,false,"div"]}],
+    {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"",false,false,"div"]}],
 ["<div>[foo</div>bar]",
     [["defaultparagraphseparator","div"],["formatblock","<div>"]],
     "<div>[foo</div><div>bar]</div>",
     [true,true],
-    {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"div",false,false,"div"]}],
+    {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"",false,false,"div"]}],
 ["<div>[foo</div>bar]",
     [["defaultparagraphseparator","p"],["formatblock","<div>"]],
     "<div>[foo</div><div>bar]</div>",
     [true,true],
-    {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"div",false,false,"div"]}],
+    {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"",false,false,"div"]}],
 ["<div style=color:blue>[foo]</div>",
     [["stylewithcss","true"],["defaultparagraphseparator","div"],["formatblock","<p>"]],
     "<p style=\"color:rgb(0, 0, 255)\">[foo]</p>",
@@ -1855,12 +1855,12 @@
     [["defaultparagraphseparator","div"],["formatblock","<h1>"]],
     "<h1>{foo<br>ba]r</h1>",
     [true,true],
-    {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"p",false,false,"h1"]}],
+    {"defaultparagraphseparator":[false,false,"p",false,false,"div"],"formatblock":[true,false,"",false,false,"h1"]}],
 ["{<p>foo</p>ba]r",
     [["defaultparagraphseparator","p"],["formatblock","<h1>"]],
     "<h1>{foo<br>ba]r</h1>",
     [true,true],
-    {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"p",false,false,"h1"]}],
+    {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"formatblock":[true,false,"",false,false,"h1"]}],
 ["<div><div contenteditable=false><span contenteditable>[foo]</span></div></div>",
     [["formatblock","p"]],
     "<div><div contenteditable=\"false\"><span contenteditable=\"\">[foo]</span></div></div>", // <span> cannot have <p>, so, do nothing
diff --git a/third_party/blink/web_tests/external/wpt/editing/run/formatblock_1-1000-expected.txt b/third_party/blink/web_tests/external/wpt/editing/run/formatblock_1-1000-expected.txt
index 31e7ff5..e0a4428 100644
--- a/third_party/blink/web_tests/external/wpt/editing/run/formatblock_1-1000-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/editing/run/formatblock_1-1000-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 1000 tests; 978 PASS, 22 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 1000 tests; 980 PASS, 20 FAIL, 0 TIMEOUT, 0 NOTRUN.
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "foo[]bar<p>extra": execCommand("defaultparagraphseparator", false, "div") return value
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "foo[]bar<p>extra": execCommand("formatblock", false, "<div>") return value
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "foo[]bar<p>extra" checks for modifications to non-editable content
@@ -770,8 +770,7 @@
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<dl><dt>[foo<dd>bar]</dl>" queryCommandIndeterm("defaultparagraphseparator") after
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<dl><dt>[foo<dd>bar]</dl>" queryCommandState("defaultparagraphseparator") after
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<dl><dt>[foo<dd>bar]</dl>" queryCommandValue("defaultparagraphseparator") after
-[FAIL] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<dl><dt>[foo<dd>bar]</dl>" queryCommandIndeterm("formatblock") before
-  assert_equals: Wrong result returned expected true but got false
+[PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<dl><dt>[foo<dd>bar]</dl>" queryCommandIndeterm("formatblock") before
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<dl><dt>[foo<dd>bar]</dl>" queryCommandState("formatblock") before
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<dl><dt>[foo<dd>bar]</dl>" queryCommandValue("formatblock") before
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<dl><dt>[foo<dd>bar]</dl>" queryCommandIndeterm("formatblock") after
@@ -788,8 +787,7 @@
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<dl><dt>[foo<dd>bar]</dl>" queryCommandIndeterm("defaultparagraphseparator") after
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<dl><dt>[foo<dd>bar]</dl>" queryCommandState("defaultparagraphseparator") after
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<dl><dt>[foo<dd>bar]</dl>" queryCommandValue("defaultparagraphseparator") after
-[FAIL] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<dl><dt>[foo<dd>bar]</dl>" queryCommandIndeterm("formatblock") before
-  assert_equals: Wrong result returned expected true but got false
+[PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<dl><dt>[foo<dd>bar]</dl>" queryCommandIndeterm("formatblock") before
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<dl><dt>[foo<dd>bar]</dl>" queryCommandState("formatblock") before
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<dl><dt>[foo<dd>bar]</dl>" queryCommandValue("formatblock") before
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<dl><dt>[foo<dd>bar]</dl>" queryCommandIndeterm("formatblock") after
diff --git a/third_party/blink/web_tests/external/wpt/editing/run/formatblock_4001-last-expected.txt b/third_party/blink/web_tests/external/wpt/editing/run/formatblock_4001-last-expected.txt
index 849dd5f..3fb8d12 100644
--- a/third_party/blink/web_tests/external/wpt/editing/run/formatblock_4001-last-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/editing/run/formatblock_4001-last-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 1034 tests; 954 PASS, 80 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 1034 tests; 964 PASS, 70 FAIL, 0 TIMEOUT, 0 NOTRUN.
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<p>"]] "<h1>[foo<br>bar]</h1>" checks for modifications to non-editable content
 [FAIL] [["defaultparagraphseparator","p"],["formatblock","<p>"]] "<h1>[foo<br>bar]</h1>" compare innerHTML
   assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<p>foo<br>bar</p>" but got "<h1>foo<br>bar</h1>"
@@ -590,8 +590,7 @@
 [FAIL] [["defaultparagraphseparator","div"],["formatblock","<h1>"]] "<p>[foo</p>bar]" queryCommandIndeterm("formatblock") before
   assert_equals: Wrong result returned expected true but got false
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<h1>"]] "<p>[foo</p>bar]" queryCommandState("formatblock") before
-[FAIL] [["defaultparagraphseparator","div"],["formatblock","<h1>"]] "<p>[foo</p>bar]" queryCommandValue("formatblock") before
-  assert_equals: Wrong result returned expected "p" but got ""
+[PASS] [["defaultparagraphseparator","div"],["formatblock","<h1>"]] "<p>[foo</p>bar]" queryCommandValue("formatblock") before
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<h1>"]] "<p>[foo</p>bar]" queryCommandIndeterm("formatblock") after
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<h1>"]] "<p>[foo</p>bar]" queryCommandState("formatblock") after
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<h1>"]] "<p>[foo</p>bar]" queryCommandValue("formatblock") after
@@ -608,8 +607,7 @@
 [FAIL] [["defaultparagraphseparator","p"],["formatblock","<h1>"]] "<p>[foo</p>bar]" queryCommandIndeterm("formatblock") before
   assert_equals: Wrong result returned expected true but got false
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<h1>"]] "<p>[foo</p>bar]" queryCommandState("formatblock") before
-[FAIL] [["defaultparagraphseparator","p"],["formatblock","<h1>"]] "<p>[foo</p>bar]" queryCommandValue("formatblock") before
-  assert_equals: Wrong result returned expected "p" but got ""
+[PASS] [["defaultparagraphseparator","p"],["formatblock","<h1>"]] "<p>[foo</p>bar]" queryCommandValue("formatblock") before
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<h1>"]] "<p>[foo</p>bar]" queryCommandIndeterm("formatblock") after
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<h1>"]] "<p>[foo</p>bar]" queryCommandState("formatblock") after
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<h1>"]] "<p>[foo</p>bar]" queryCommandValue("formatblock") after
@@ -831,8 +829,7 @@
 [FAIL] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<p>[foo<h1>bar]</h1>" queryCommandIndeterm("formatblock") before
   assert_equals: Wrong result returned expected true but got false
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<p>[foo<h1>bar]</h1>" queryCommandState("formatblock") before
-[FAIL] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<p>[foo<h1>bar]</h1>" queryCommandValue("formatblock") before
-  assert_equals: Wrong result returned expected "p" but got ""
+[PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<p>[foo<h1>bar]</h1>" queryCommandValue("formatblock") before
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<p>[foo<h1>bar]</h1>" queryCommandIndeterm("formatblock") after
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<p>[foo<h1>bar]</h1>" queryCommandState("formatblock") after
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<p>[foo<h1>bar]</h1>" queryCommandValue("formatblock") after
@@ -850,8 +847,7 @@
 [FAIL] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<p>[foo<h1>bar]</h1>" queryCommandIndeterm("formatblock") before
   assert_equals: Wrong result returned expected true but got false
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<p>[foo<h1>bar]</h1>" queryCommandState("formatblock") before
-[FAIL] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<p>[foo<h1>bar]</h1>" queryCommandValue("formatblock") before
-  assert_equals: Wrong result returned expected "p" but got ""
+[PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<p>[foo<h1>bar]</h1>" queryCommandValue("formatblock") before
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<p>[foo<h1>bar]</h1>" queryCommandIndeterm("formatblock") after
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<p>[foo<h1>bar]</h1>" queryCommandState("formatblock") after
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<p>[foo<h1>bar]</h1>" queryCommandValue("formatblock") after
@@ -869,8 +865,7 @@
 [FAIL] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<h1>[foo</h1><h2>bar]</h2>" queryCommandIndeterm("formatblock") before
   assert_equals: Wrong result returned expected true but got false
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<h1>[foo</h1><h2>bar]</h2>" queryCommandState("formatblock") before
-[FAIL] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<h1>[foo</h1><h2>bar]</h2>" queryCommandValue("formatblock") before
-  assert_equals: Wrong result returned expected "h1" but got ""
+[PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<h1>[foo</h1><h2>bar]</h2>" queryCommandValue("formatblock") before
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<h1>[foo</h1><h2>bar]</h2>" queryCommandIndeterm("formatblock") after
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<h1>[foo</h1><h2>bar]</h2>" queryCommandState("formatblock") after
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<h1>[foo</h1><h2>bar]</h2>" queryCommandValue("formatblock") after
@@ -888,8 +883,7 @@
 [FAIL] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<h1>[foo</h1><h2>bar]</h2>" queryCommandIndeterm("formatblock") before
   assert_equals: Wrong result returned expected true but got false
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<h1>[foo</h1><h2>bar]</h2>" queryCommandState("formatblock") before
-[FAIL] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<h1>[foo</h1><h2>bar]</h2>" queryCommandValue("formatblock") before
-  assert_equals: Wrong result returned expected "h1" but got ""
+[PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<h1>[foo</h1><h2>bar]</h2>" queryCommandValue("formatblock") before
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<h1>[foo</h1><h2>bar]</h2>" queryCommandIndeterm("formatblock") after
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<h1>[foo</h1><h2>bar]</h2>" queryCommandState("formatblock") after
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<h1>[foo</h1><h2>bar]</h2>" queryCommandValue("formatblock") after
@@ -906,8 +900,7 @@
 [FAIL] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<div>[foo</div>bar]" queryCommandIndeterm("formatblock") before
   assert_equals: Wrong result returned expected true but got false
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<div>[foo</div>bar]" queryCommandState("formatblock") before
-[FAIL] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<div>[foo</div>bar]" queryCommandValue("formatblock") before
-  assert_equals: Wrong result returned expected "div" but got ""
+[PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<div>[foo</div>bar]" queryCommandValue("formatblock") before
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<div>[foo</div>bar]" queryCommandIndeterm("formatblock") after
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<div>[foo</div>bar]" queryCommandState("formatblock") after
 [FAIL] [["defaultparagraphseparator","div"],["formatblock","<div>"]] "<div>[foo</div>bar]" queryCommandValue("formatblock") after
@@ -925,8 +918,7 @@
 [FAIL] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<div>[foo</div>bar]" queryCommandIndeterm("formatblock") before
   assert_equals: Wrong result returned expected true but got false
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<div>[foo</div>bar]" queryCommandState("formatblock") before
-[FAIL] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<div>[foo</div>bar]" queryCommandValue("formatblock") before
-  assert_equals: Wrong result returned expected "div" but got ""
+[PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<div>[foo</div>bar]" queryCommandValue("formatblock") before
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<div>[foo</div>bar]" queryCommandIndeterm("formatblock") after
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<div>[foo</div>bar]" queryCommandState("formatblock") after
 [FAIL] [["defaultparagraphseparator","p"],["formatblock","<div>"]] "<div>[foo</div>bar]" queryCommandValue("formatblock") after
@@ -1037,8 +1029,7 @@
 [FAIL] [["defaultparagraphseparator","div"],["formatblock","<h1>"]] "{<p>foo</p>ba]r" queryCommandIndeterm("formatblock") before
   assert_equals: Wrong result returned expected true but got false
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<h1>"]] "{<p>foo</p>ba]r" queryCommandState("formatblock") before
-[FAIL] [["defaultparagraphseparator","div"],["formatblock","<h1>"]] "{<p>foo</p>ba]r" queryCommandValue("formatblock") before
-  assert_equals: Wrong result returned expected "p" but got ""
+[PASS] [["defaultparagraphseparator","div"],["formatblock","<h1>"]] "{<p>foo</p>ba]r" queryCommandValue("formatblock") before
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<h1>"]] "{<p>foo</p>ba]r" queryCommandIndeterm("formatblock") after
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<h1>"]] "{<p>foo</p>ba]r" queryCommandState("formatblock") after
 [PASS] [["defaultparagraphseparator","div"],["formatblock","<h1>"]] "{<p>foo</p>ba]r" queryCommandValue("formatblock") after
@@ -1055,8 +1046,7 @@
 [FAIL] [["defaultparagraphseparator","p"],["formatblock","<h1>"]] "{<p>foo</p>ba]r" queryCommandIndeterm("formatblock") before
   assert_equals: Wrong result returned expected true but got false
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<h1>"]] "{<p>foo</p>ba]r" queryCommandState("formatblock") before
-[FAIL] [["defaultparagraphseparator","p"],["formatblock","<h1>"]] "{<p>foo</p>ba]r" queryCommandValue("formatblock") before
-  assert_equals: Wrong result returned expected "p" but got ""
+[PASS] [["defaultparagraphseparator","p"],["formatblock","<h1>"]] "{<p>foo</p>ba]r" queryCommandValue("formatblock") before
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<h1>"]] "{<p>foo</p>ba]r" queryCommandIndeterm("formatblock") after
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<h1>"]] "{<p>foo</p>ba]r" queryCommandState("formatblock") after
 [PASS] [["defaultparagraphseparator","p"],["formatblock","<h1>"]] "{<p>foo</p>ba]r" queryCommandValue("formatblock") after
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.drawing.style.letterSpacing.change.font.html b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.drawing.style.letterSpacing.change.font.html
index 74774b5..daff0cf 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.drawing.style.letterSpacing.change.font.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/element/text/2d.text.drawing.style.letterSpacing.change.font.html
@@ -29,7 +29,7 @@
   // 1em = 10px. Add 10px after each letter in "Hello World",
   // makes it 110px longer.
   var width_with_spacing = ctx.measureText('Hello World').width;
-  _assertSame(width_with_spacing, width_normal + 110, "width_with_spacing", "width_normal + 110");
+  assert_approx_equals(width_with_spacing, width_normal + 110, 0.1, "letter-spacing error");
 
   // Changing font to 20px. Without resetting the spacing, 1em letterSpacing
   // is now 20px, so it's suppose to be 220px longer without any letterSpacing set.
@@ -38,7 +38,7 @@
   // Now calculate the reference spacing for "Hello World" with no spacing.
   ctx.letterSpacing = '0em';
   width_normal = ctx.measureText('Hello World').width;
-  _assertSame(width_with_spacing, width_normal + 220, "width_with_spacing", "width_normal + 220");
+  assert_approx_equals(width_with_spacing, width_normal + 220, 0.1, "letter-spacing error after font change");
 
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.change.font.html b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.change.font.html
index 636f719..f8b45341 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.change.font.html
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.change.font.html
@@ -30,7 +30,7 @@
   // 1em = 10px. Add 10px after each letter in "Hello World",
   // makes it 110px longer.
   var width_with_spacing = ctx.measureText('Hello World').width;
-  _assertSame(width_with_spacing, width_normal + 110, "width_with_spacing", "width_normal + 110");
+  assert_approx_equals(width_with_spacing, width_normal + 110, 0.1, "letter-spacing error");
 
   // Changing font to 20px. Without resetting the spacing, 1em letterSpacing
   // is now 20px, so it's suppose to be 220px longer without any letterSpacing set.
@@ -39,7 +39,7 @@
   // Now calculate the reference spacing for "Hello World" with no spacing.
   ctx.letterSpacing = '0em';
   width_normal = ctx.measureText('Hello World').width;
-  _assertSame(width_with_spacing, width_normal + 220, "width_with_spacing", "width_normal + 220");
+  assert_approx_equals(width_with_spacing, width_normal + 220, 0.1, "letter-spacing error after font change");
   t.done();
 
 });
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.change.font.worker.js b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.change.font.worker.js
index 22fb04f..510845c8 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.change.font.worker.js
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/offscreen/text/2d.text.drawing.style.letterSpacing.change.font.worker.js
@@ -26,7 +26,7 @@
   // 1em = 10px. Add 10px after each letter in "Hello World",
   // makes it 110px longer.
   var width_with_spacing = ctx.measureText('Hello World').width;
-  _assertSame(width_with_spacing, width_normal + 110, "width_with_spacing", "width_normal + 110");
+  assert_approx_equals(width_with_spacing, width_normal + 110, 0.1, "letter-spacing error");
 
   // Changing font to 20px. Without resetting the spacing, 1em letterSpacing
   // is now 20px, so it's suppose to be 220px longer without any letterSpacing set.
@@ -35,7 +35,7 @@
   // Now calculate the reference spacing for "Hello World" with no spacing.
   ctx.letterSpacing = '0em';
   width_normal = ctx.measureText('Hello World').width;
-  _assertSame(width_with_spacing, width_normal + 220, "width_with_spacing", "width_normal + 220");
+  assert_approx_equals(width_with_spacing, width_normal + 220, 0.1, "letter-spacing error after font change");
   t.done();
 });
 done();
diff --git a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/text.yaml b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/text.yaml
index 8bbc874..ca945c2 100644
--- a/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/text.yaml
+++ b/third_party/blink/web_tests/external/wpt/html/canvas/tools/yaml-new/text.yaml
@@ -1343,7 +1343,7 @@
     // 1em = 10px. Add 10px after each letter in "Hello World",
     // makes it 110px longer.
     var width_with_spacing = ctx.measureText('Hello World').width;
-    @assert width_with_spacing === width_normal + 110;
+    assert_approx_equals(width_with_spacing, width_normal + 110, 0.1, "letter-spacing error");
 
     // Changing font to 20px. Without resetting the spacing, 1em letterSpacing
     // is now 20px, so it's suppose to be 220px longer without any letterSpacing set.
@@ -1352,7 +1352,7 @@
     // Now calculate the reference spacing for "Hello World" with no spacing.
     ctx.letterSpacing = '0em';
     width_normal = ctx.measureText('Hello World').width;
-    @assert width_with_spacing === width_normal + 220;
+    assert_approx_equals(width_with_spacing, width_normal + 220, 0.1, "letter-spacing error after font change");
 
 - name: 2d.text.drawing.style.wordSpacing.change.font
   desc: Set word spacing and word spacing to font dependent value and verify it works after font change.
@@ -1677,4 +1677,4 @@
   code: |
     ctx.font = "math serif";
 
-# TODO: shadows, alpha, composite, clip
\ No newline at end of file
+# TODO: shadows, alpha, composite, clip
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/documents/resource-metadata-management/document-lastModified-01.html b/third_party/blink/web_tests/external/wpt/html/dom/documents/resource-metadata-management/document-lastModified-01.html
index 4d9d870..81f6739 100644
--- a/third_party/blink/web_tests/external/wpt/html/dom/documents/resource-metadata-management/document-lastModified-01.html
+++ b/third_party/blink/web_tests/external/wpt/html/dom/documents/resource-metadata-management/document-lastModified-01.html
@@ -3,101 +3,23 @@
 <meta name="timeout" content="long">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src="support/document-lastModified-utils.js"></script>
 <div id="log"></div>
 <script>
   var last_modified = document.lastModified;
 
-  var pattern = /^([0-9]{2})\/([0-9]{2})\/([0-9]{4}) ([0-9]{2}):([0-9]{2}):([0-9]{2})$/;
-
   test(function() {
-     assert_regexp_match(last_modified, pattern,
+     assert_regexp_match(last_modified, DOCUMENT_LASTMODIFIED_REGEX,
                          "Format should match the pattern \"NN/NN/NNNN NN:NN:NN\".");
   }, "Date returned by lastModified is in the form \"MM/DD/YYYY hh:mm:ss\".");
 
-  function assert_date_string_approximately_now(str) {
-    // We want to test that |str| was a time in the user's local
-    // timezone generated within a few seconds prior to the present.
-    // This requires some care, since it is possible that:
-    //  - the few second difference may have crossed a
-    //    year/month/day/hour/minute boundary
-    //  - the few second difference may have crossed a change in the
-    //    local timezone's UTC offset
-    //  - the local time might be one that has multiple valid UTC
-    //    representations (for example, because it's in the hour
-    //    following a shift from summer time to winter time)
-    // We will make some assumptions to do this:
-    //  - local time's UTC offset doesn't change more than once per
-    //    minute
-    //  - local time's UTC offset only changes by integral numbers of
-    //    minutes
-
-    // The date must be equal to or earlier than the present time.
-    var dmax = new Date();
-
-    // The date must be equal to or later than 2.5 seconds ago.
-    var TOLERANCE_MILLISECONDS = 2500;
-    var dmin = new Date();
-    dmin.setTime(dmax.getTime() - TOLERANCE_MILLISECONDS);
-
-    // Extract the year/month/date/hours/minutes/seconds from str.  It
-    // is important that we do *not* try to construct a Date object from
-    // these, since the core of the date object is a timestamp in UTC,
-    // and there are cases (such as the hour on each side of a change
-    // from summer time to winter time) where there are multiple
-    // possible UTC timestamps for a given YYYY-MM-DD HH:MM:SS, and
-    // constructing a Date object would pick one of them, which might be
-    // the wrong one.  However, we already have the right one in dmin
-    // and dmax, so we should instead extract local time from those
-    // rather than converting these values to UTC.
-    var m = pattern.exec(str);
-    var syear = Number(m[3]);
-    var smonth = Number(m[1]) - 1; // match Javascript 0-based months
-    var sdate = Number(m[2]);
-    var shours = Number(m[4]);
-    var sminutes = Number(m[5]);
-    var sseconds = Number(m[6]);
-
-    if (dmin.getFullYear() == dmax.getFullYear() &&
-        dmin.getMonth() == dmax.getMonth() &&
-        dmin.getDate() == dmax.getDate() &&
-        dmin.getHours() == dmax.getHours() &&
-        dmin.getMinutes() == dmax.getMinutes()) {
-      // min and max have the same minute
-      assert_equals(smonth, dmin.getMonth(), "month");
-      assert_equals(sdate, dmin.getDate(), "date");
-      assert_equals(syear, dmin.getFullYear(), "year");
-      assert_equals(shours, dmin.getHours(), "hours");
-      assert_equals(sminutes, dmin.getMinutes(), "minutes");
-      assert_true(dmin.getSeconds() <= sseconds &&
-                  sseconds <= dmax.getSeconds(), "seconds");
-    } else if (dmin.getFullYear() == syear &&
-               dmin.getMonth() == smonth &&
-               dmin.getDate() == sdate &&
-               dmin.getHours() == shours &&
-               dmin.getMinutes() == sminutes) {
-      // actual value has the same minute as min
-      assert_true(dmin.getSeconds() <= sseconds, "dmin.getSeconds() <= sseconds");
-      assert_true(57 <= dmin.getSeconds(), "unexpected local time rules (dmin match)");
-    } else if (dmax.getFullYear() == syear &&
-               dmax.getMonth() == smonth &&
-               dmax.getDate() == sdate &&
-               dmax.getHours() == shours &&
-               dmax.getMinutes() == sminutes) {
-      // actual value has the same minute as max
-      assert_true(sseconds <= dmax.getSeconds(), "sseconds <= dmax.getSeconds()");
-      assert_true(dmax.getSeconds() <= 2, "unexpected local time rules (dmax match)");
-    } else {
-      assert_unreached("unexpected local time rules (no match)");
-    }
-  }
-
   test(function() {
-    assert_date_string_approximately_now(last_modified);
+    assert_document_lastmodified_string_approximately_now(last_modified);
   }, "Date returned by lastModified is current at page load");
 
   var t = async_test("Date returned by lastModified is current after timeout.");
   t.step_timeout(function() {
-    assert_date_string_approximately_now(document.lastModified);
+    assert_document_lastmodified_string_approximately_now(document.lastModified);
     t.done();
   }, 4000);
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/documents/resource-metadata-management/support/document-lastModified-utils.js b/third_party/blink/web_tests/external/wpt/html/dom/documents/resource-metadata-management/support/document-lastModified-utils.js
new file mode 100644
index 0000000..bbcde18
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/dom/documents/resource-metadata-management/support/document-lastModified-utils.js
@@ -0,0 +1,78 @@
+const DOCUMENT_LASTMODIFIED_REGEX = /^([0-9]{2})\/([0-9]{2})\/([0-9]{4}) ([0-9]{2}):([0-9]{2}):([0-9]{2})$/;
+
+function assert_document_lastmodified_string_approximately_now(str) {
+  // We want to test that |str| was a time in the user's local
+  // timezone generated within a few seconds prior to the present.
+  // This requires some care, since it is possible that:
+  //  - the few second difference may have crossed a
+  //    year/month/day/hour/minute boundary
+  //  - the few second difference may have crossed a change in the
+  //    local timezone's UTC offset
+  //  - the local time might be one that has multiple valid UTC
+  //    representations (for example, because it's in the hour
+  //    following a shift from summer time to winter time)
+  // We will make some assumptions to do this:
+  //  - local time's UTC offset doesn't change more than once per
+  //    minute
+  //  - local time's UTC offset only changes by integral numbers of
+  //    minutes
+
+  // The date must be equal to or earlier than the present time.
+  var dmax = new Date();
+
+  // The date must be equal to or later than 2.5 seconds ago.
+  var TOLERANCE_MILLISECONDS = 2500;
+  var dmin = new Date();
+  dmin.setTime(dmax.getTime() - TOLERANCE_MILLISECONDS);
+
+  // Extract the year/month/date/hours/minutes/seconds from str.  It
+  // is important that we do *not* try to construct a Date object from
+  // these, since the core of the date object is a timestamp in UTC,
+  // and there are cases (such as the hour on each side of a change
+  // from summer time to winter time) where there are multiple
+  // possible UTC timestamps for a given YYYY-MM-DD HH:MM:SS, and
+  // constructing a Date object would pick one of them, which might be
+  // the wrong one.  However, we already have the right one in dmin
+  // and dmax, so we should instead extract local time from those
+  // rather than converting these values to UTC.
+  var m = DOCUMENT_LASTMODIFIED_REGEX.exec(str);
+  var syear = Number(m[3]);
+  var smonth = Number(m[1]) - 1; // match Javascript 0-based months
+  var sdate = Number(m[2]);
+  var shours = Number(m[4]);
+  var sminutes = Number(m[5]);
+  var sseconds = Number(m[6]);
+
+  if (dmin.getFullYear() == dmax.getFullYear() &&
+      dmin.getMonth() == dmax.getMonth() &&
+      dmin.getDate() == dmax.getDate() &&
+      dmin.getHours() == dmax.getHours() &&
+      dmin.getMinutes() == dmax.getMinutes()) {
+    // min and max have the same minute
+    assert_equals(smonth, dmin.getMonth(), "month");
+    assert_equals(sdate, dmin.getDate(), "date");
+    assert_equals(syear, dmin.getFullYear(), "year");
+    assert_equals(shours, dmin.getHours(), "hours");
+    assert_equals(sminutes, dmin.getMinutes(), "minutes");
+    assert_true(dmin.getSeconds() <= sseconds &&
+                sseconds <= dmax.getSeconds(), "seconds");
+  } else if (dmin.getFullYear() == syear &&
+             dmin.getMonth() == smonth &&
+             dmin.getDate() == sdate &&
+             dmin.getHours() == shours &&
+             dmin.getMinutes() == sminutes) {
+    // actual value has the same minute as min
+    assert_true(dmin.getSeconds() <= sseconds, "dmin.getSeconds() <= sseconds");
+    assert_true(57 <= dmin.getSeconds(), "unexpected local time rules (dmin match)");
+  } else if (dmax.getFullYear() == syear &&
+             dmax.getMonth() == smonth &&
+             dmax.getDate() == sdate &&
+             dmax.getHours() == shours &&
+             dmax.getMinutes() == sminutes) {
+    // actual value has the same minute as max
+    assert_true(sseconds <= dmax.getSeconds(), "sseconds <= dmax.getSeconds()");
+    assert_true(dmax.getSeconds() <= 2, "unexpected local time rules (dmax match)");
+  } else {
+    assert_unreached("unexpected local time rules (no match)");
+  }
+}
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/invokers/invoketarget-fullscreen-behavior.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/invokers/invoketarget-fullscreen-behavior.tentative.html
new file mode 100644
index 0000000..09f8969
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/invokers/invoketarget-fullscreen-behavior.tentative.html
@@ -0,0 +1,164 @@
+<!doctype html>
+<meta charset="utf-8" />
+<meta name="author" title="Luke Warlow" href="mailto:luke@warlow.dev" />
+<link rel="help" href="https://open-ui.org/components/invokers.explainer/" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-actions.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="resources/invoker-utils.js"></script>
+
+<div id="invokee">
+  Fullscreen content
+  <button id="invokerbutton" invoketarget="invokee"></button>
+</div>
+
+<script>
+  // auto
+
+  promise_test(async function (t) {
+    t.add_cleanup(async () => {
+      if (document.fullscreenElement) await document.exitFullscreen();
+    });
+    assert_false(invokee.matches(":fullscreen"));
+    await clickOn(invokerbutton);
+    assert_false(invokee.matches(":fullscreen"));
+  }, "invoking div with auto action is no-op");
+
+  // toggleFullscreen
+
+  promise_test(async function (t) {
+    t.add_cleanup(async () => {
+      invokerbutton.removeAttribute("invokeaction");
+      if (document.fullscreenElement) await document.exitFullscreen();
+    });
+    assert_false(invokee.matches(":fullscreen"));
+    invokerbutton.setAttribute("invokeaction", "toggleFullscreen");
+    await clickOn(invokerbutton);
+    assert_true(invokee.matches(":fullscreen"));
+  }, "invoking div with toggleFullscreen action makes div fullscreen");
+
+  promise_test(async function (t) {
+    t.add_cleanup(async () => {
+      invokerbutton.removeAttribute("invokeaction");
+      if (document.fullscreenElement) await document.exitFullscreen();
+    });
+    invokee.addEventListener("invoke", (e) => e.preventDefault(), {
+      once: true,
+    });
+    assert_false(invokee.matches(":fullscreen"));
+    invokerbutton.setAttribute("invokeaction", "toggleFullscreen");
+    await clickOn(invokerbutton);
+    assert_false(invokee.matches(":fullscreen"));
+  }, "invoking div with toggleFullscreen action and preventDefault is a no-op");
+
+  promise_test(async function (t) {
+    t.add_cleanup(async () => {
+      invokerbutton.removeAttribute("invokeaction");
+      if (document.fullscreenElement) await document.exitFullscreen();
+    });
+    invokerbutton.setAttribute("invokeaction", "toggleFullscreen");
+    await test_driver.bless('go fullscreen');
+    await invokee.requestFullscreen();
+    assert_true(invokee.matches(":fullscreen"));
+    await clickOn(invokerbutton);
+    assert_false(invokee.matches(":fullscreen"));
+  }, "invoking fullscreen div with toggleFullscreen action exits fullscreen");
+
+  promise_test(async function (t) {
+    t.add_cleanup(async () => {
+      invokerbutton.removeAttribute("invokeaction");
+      if (document.fullscreenElement) await document.exitFullscreen();
+    });
+    invokerbutton.setAttribute("invokeaction", "tOgGlEFullscreen");
+    await test_driver.bless('go fullscreen');
+    await invokee.requestFullscreen();
+    assert_true(invokee.matches(":fullscreen"));
+    await clickOn(invokerbutton);
+    assert_false(invokee.matches(":fullscreen"));
+  }, "invoking fullscreen div with toggleFullscreen (case-insensitive) action exits fullscreen");
+
+  // requestFullscreen
+
+  promise_test(async function (t) {
+    t.add_cleanup(async () => {
+      invokerbutton.removeAttribute("invokeaction");
+      if (document.fullscreenElement) await document.exitFullscreen();
+    });
+    assert_false(invokee.matches(":fullscreen"));
+    invokerbutton.setAttribute("invokeaction", "requestFullscreen");
+    await clickOn(invokerbutton);
+    assert_true(invokee.matches(":fullscreen"));
+  }, "invoking div with requestFullscreen action makes div fullscreen");
+
+  promise_test(async function (t) {
+    t.add_cleanup(async () => {
+      invokerbutton.removeAttribute("invokeaction");
+      if (document.fullscreenElement) await document.exitFullscreen();
+    });
+    invokee.addEventListener("invoke", (e) => e.preventDefault(), {
+      once: true,
+    });
+    assert_false(invokee.matches(":fullscreen"));
+    invokerbutton.setAttribute("invokeaction", "requestFullscreen");
+    await clickOn(invokerbutton);
+    assert_false(invokee.matches(":fullscreen"));
+  }, "invoking div with requestFullscreen action and preventDefault is a no-op");
+
+  promise_test(async function (t) {
+    t.add_cleanup(async () => {
+      invokerbutton.removeAttribute("invokeaction");
+      if (document.fullscreenElement) await document.exitFullscreen();
+    });
+    invokerbutton.setAttribute("invokeaction", "requestFullscreen");
+    await test_driver.bless('go fullscreen');
+    await invokee.requestFullscreen();
+    assert_true(invokee.matches(":fullscreen"));
+    await clickOn(invokerbutton);
+    assert_true(invokee.matches(":fullscreen"));
+  }, "invoking fullscreen div with requestFullscreen action is a no-op");
+
+  // exitFullscreen
+
+  promise_test(async function (t) {
+    t.add_cleanup(async () => {
+      invokerbutton.removeAttribute("invokeaction");
+      if (document.fullscreenElement) await document.exitFullscreen();
+    });
+    assert_false(invokee.matches(":fullscreen"));
+    invokerbutton.setAttribute("invokeaction", "exitFullscreen");
+    await clickOn(invokerbutton);
+    assert_false(invokee.matches(":fullscreen"));
+  }, "invoking div with exitFullscreen action is a no-op");
+
+  promise_test(async function (t) {
+    t.add_cleanup(async () => {
+      invokerbutton.removeAttribute("invokeaction");
+      if (document.fullscreenElement) await document.exitFullscreen();
+    });
+    invokerbutton.setAttribute("invokeaction", "exitFullscreen");
+    await test_driver.bless('go fullscreen');
+    await invokee.requestFullscreen();
+    assert_true(invokee.matches(":fullscreen"));
+    await clickOn(invokerbutton);
+    assert_false(invokee.matches(":fullscreen"));
+  }, "invoking fullscreen div with exitFullscreen action exits fullscreen");
+
+  promise_test(async function (t) {
+    t.add_cleanup(async () => {
+      invokerbutton.removeAttribute("invokeaction");
+      if (document.fullscreenElement) await document.exitFullscreen();
+    });
+    invokee.addEventListener("invoke", (e) => e.preventDefault(), {
+      once: true,
+    });
+    invokerbutton.setAttribute("invokeaction", "exitFullscreen");
+    await test_driver.bless('go fullscreen');
+    await invokee.requestFullscreen();
+    assert_true(invokee.matches(":fullscreen"));
+    await clickOn(invokerbutton);
+    assert_true(invokee.matches(":fullscreen"));
+  }, "invoking fullscreen div with exitFullscreen action and preventDefault is a no-op");
+
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/performance-timeline/navigation-id-initial-load.tentative.html b/third_party/blink/web_tests/external/wpt/performance-timeline/navigation-id-initial-load.tentative.html
index 93ddcff..b996f0f1 100644
--- a/third_party/blink/web_tests/external/wpt/performance-timeline/navigation-id-initial-load.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/performance-timeline/navigation-id-initial-load.tentative.html
@@ -28,7 +28,7 @@
       // Assert navigation id exists in a NavigationTiming entry.
       const navigationIdOfNavigationTiming =
         performance.getEntriesByType('navigation')[0].navigationId;
-      assert_not_equals(navigationIdOfNavigationTiming, null,
+      assert_true(!!navigationIdOfNavigationTiming,
         'Navigation Id of a navigation timing entry should exist at initial navigation');
 
       // Assert navigation id exists in PaintTiming entries and are all the same.
diff --git a/third_party/blink/web_tests/external/wpt/webcodecs/full-cycle-test.https.any.js b/third_party/blink/web_tests/external/wpt/webcodecs/full-cycle-test.https.any.js
index d2e4ad94..b7d5f7ea 100644
--- a/third_party/blink/web_tests/external/wpt/webcodecs/full-cycle-test.https.any.js
+++ b/third_party/blink/web_tests/external/wpt/webcodecs/full-cycle-test.https.any.js
@@ -156,8 +156,12 @@
   await decoder.flush();
   encoder.close();
   decoder.close();
-  assert_equals(frames_encoded, frames_to_encode, "frames_encoded");
-  assert_equals(frames_decoded, frames_to_encode, "frames_decoded");
+  if (options.realTimeLatencyMode) {
+    assert_greater_than(frames_encoded, 0, "frames_encoded");
+  } else {
+    assert_equals(frames_encoded, frames_to_encode, "frames_encoded");
+  }
+  assert_equals(frames_decoded, frames_encoded, "frames_decoded");
 }
 
 promise_test(async t => {
diff --git a/third_party/blink/web_tests/external/wpt/webnn/softsign.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/webnn/softsign.https.any-expected.txt
deleted file mode 100644
index 0eba8b5..0000000
--- a/third_party/blink/web_tests/external/wpt/webnn/softsign.https.any-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-This is a testharness.js-based test.
-[FAIL] softsign positive float32 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
-[FAIL] softsign negative float32 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
-[FAIL] softsign float32 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
-[FAIL] softsign float32 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
-[FAIL] softsign float32 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
-[FAIL] softsign float32 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/xhr/responsexml-document-properties.htm b/third_party/blink/web_tests/external/wpt/xhr/responsexml-document-properties.htm
index a9f14f8..1d2811b 100644
--- a/third_party/blink/web_tests/external/wpt/xhr/responsexml-document-properties.htm
+++ b/third_party/blink/web_tests/external/wpt/xhr/responsexml-document-properties.htm
@@ -4,11 +4,11 @@
     <title>XMLHttpRequest: responseXML document properties</title>
     <script src="/resources/testharness.js"></script>
     <script src="/resources/testharnessreport.js"></script>
+    <script src="../html/dom/documents/resource-metadata-management/support/document-lastModified-utils.js"></script>
   </head>
   <body>
     <div id="log"></div>
     <script>
-      var timePreXHR = Math.floor(new Date().getTime(new Date().getTime() - 3000) / 1000); // three seconds ago, in case there's clock drift
       var client = new XMLHttpRequest()
       client.open("GET", "resources/well-formed.xml", false)
       client.send(null)
@@ -87,10 +87,7 @@
       }, "Test document URL properties of document with <base> after redirect");
 
       test(function() {
-        var lastModified = Math.floor(parseLastModified(client.responseXML.lastModified).getTime() / 1000);
-        var now = Math.floor(new Date().getTime(new Date().getTime() + 3000) / 1000); // three seconds from now, in case there's clock drift
-        assert_greater_than_equal(lastModified, timePreXHR);
-        assert_less_than_equal(lastModified, now);
+        assert_document_lastmodified_string_approximately_now(client.responseXML.lastModified);
       }, 'lastModified set to time of response if no HTTP header provided')
 
       test(function() {
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/attribution-reporting/source-registered-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/attribution-reporting/source-registered-expected.txt
index dea6bfc2..bc4fa25e 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/attribution-reporting/source-registered-expected.txt
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/attribution-reporting/source-registered-expected.txt
@@ -12,12 +12,6 @@
             [0] : https://a.example
         ]
         eventId : 123
-        eventReportWindows : {
-            ends : [
-                [0] : 86400
-            ]
-            start : 0
-        }
         expiry : 2592000
         filterData : [
             [0] : {
@@ -33,6 +27,20 @@
         sourceOrigin : <string>
         time : <number>
         triggerDataMatching : modulus
+        triggerSpecs : [
+            [0] : {
+                eventReportWindows : {
+                    ends : [
+                        [0] : 86400
+                    ]
+                    start : 0
+                }
+                triggerData : [
+                    [0] : 0
+                    [1] : 1
+                ]
+            }
+        ]
         type : event
     }
     result : success
diff --git a/third_party/blink/web_tests/http/tests/lcp_critical_path_predictor/prioritize_lcp_image.php b/third_party/blink/web_tests/http/tests/lcp_critical_path_predictor/prioritize_lcp_image.php
index 4ec3b216..0f72299 100644
--- a/third_party/blink/web_tests/http/tests/lcp_critical_path_predictor/prioritize_lcp_image.php
+++ b/third_party/blink/web_tests/http/tests/lcp_critical_path_predictor/prioritize_lcp_image.php
@@ -53,6 +53,11 @@
 
     assert_equals(hint_matched_img_priority, kMedium);
   }, "Ensure non-LCPP hinted images were loaded unaffected with Medium priority.")
+
+  promise_test(async t => {
+    const lcp_elment = await internals.LCPPrediction(document);
+    assert_equals(lcp_elment, "/#lcp_image");
+  }, "Ensure document::RunLCPPredictedCallbacks is called with LCP element locator.")
 </script>
 <img src="/resources/square.png" id="lcp_image">
 <img src="/resources/square100.png">
diff --git a/third_party/blink/web_tests/media/sources-fallback-codecs.html b/third_party/blink/web_tests/media/sources-fallback-codecs.html
index 6df41aea..48fbaf42 100644
--- a/third_party/blink/web_tests/media/sources-fallback-codecs.html
+++ b/third_party/blink/web_tests/media/sources-fallback-codecs.html
@@ -9,24 +9,11 @@
 // all hit canplaythrough is good enough. Someday when many more
 // files are present, consider generalizing this.
 
-// The base64'd data below was generated from the corresponding content/test.{mp4,ogv}files with:
-// rm -f test-frame.ogv test-frame.mp4 and
-// ~/tmp/ffmpeg/ffmpeg -i test.mp4 -an -vframes 1 test-frame.png and
-// pngtopnm test-frame.png > test-frame.pnm && pnmscale 0.25 test-frame.pnm|pnmtopng > test-frame.png and
-// ~/tmp/ffmpeg/ffmpeg -i test-frame.png -an -vframes 1 -s 80x60 test-frame.mp4 and
-// ffmpeg2theora test-frame.mp4 -o test-frame.ogv && rm test-frame.png test-frame.pnm
-// Followed by [base64 -w 120 test-frame.ogv] and [base64 -w 120 test-frame.mp4].
-var mp4DataSrc = "data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAHuG1kYXQAAAGzABAHAAABthBgdgpU4Bg8SyD1tWXqqBr13UzOZBxmb/64MV3Y2OWRzRBZvxztjdtC0aswA4S201VqgQ/Np60Xf8OUmDifBg+95svvk+lsTg4EMuv6x9WzQbpfFfpARTAuyg4uzeDkGWlUS9HIed50tZ6pNjlvoEfjd6hclYB4KApmDwRrAZTg4Zawfliu78GzrSRSn2346BT23GdS+aoN6cTJARID4MA79lWcA4kA03AYcp4mBVsNlk9hYqEJW20JJePwNxJqthUyX/HNYEHS8P79hhLN0z88EBKyOd+B1NqZkSmM3f98PYrSpxGVM3yYDZa0O1fh/5O2X+YZUK2WVYfe/n3HgYtxtM0pHQkA8H/zsj2RQX80S0+Kh2rBCgMv2gdVpR+r98t6k36bRyJE2B8AxqxLxhod7g6EhYQ8T3vi/jReXfANEtMOmQZcHg/+cG6IybfRqtMAigG43g6Z1uA+D/0/aXh2JCpWr94eCSlZrbKZU1oKZujuwvCGCnA1qcvxZJ/BJmgxb9VRA6Boch+DAJF7KUeYOvCXiYEVpOCmEDGmmByrBhy3GFUgf6x6DnR3VI5/6SMt3auZC58DgjfA2pLsBxfufZsv8t3N/+XLmysB62z/RALC37Kv/1Ost0zGiEOtD/qbAYriTG1CnwPBwC96PlF9crWpNK1WtFmtbJuWXJXfMuPghiUJbPmPD5vitVGYrbYTRq62XKh3U1AzrIfgiBDjegrA+o5V5Fe/LTAuD5igwiNL96HmL9LeoEIgs9Njn4EdPlGBGHSZmK1SRppvFUSZfLTGMxr0zPB1A8VKvXZimtKlXrb5hqGI+2HzFBhEaX70PMX6W9QIRBZ6bHPwI6ftWqYrDIKxq9abBkGb1TjfVhAZUqRBb7BAb6Ofh58t3DNZ/zcU+3P4HOWbBi6Fa7DMRgY+tzvSqoCxnpQIDfQIfGz/fwAAlGlBJKl2GEIGPL970qiEtZ6UiC30CPxu+GqXYYQgY8v3vSqIS1npSILfQI/G738bbfztogcuLou9sK/swqEtInsxr+92bvi1hlgtmXmlgg+8WqKN1HVBCDrB4D8vBkoQ2wPlwMmSfSphCwdYPU/vVRBDZZZV+l0cbQ/LlWJgMZvIH9Z3/rfNVx8eDofsfLv61+AaBTjmfS437cZn7PJml418ciBRz33Mz+LgLCKDD8GA4OgD+AHpWtCEJYHE/x+Oh+qbTKPqtxVlEgv8IrTbebfcAtv7xTG22hb9hwB4CB7BtA6DKgYegGRN9P4uEMSx4PB2OqWiAP0g9V4mLQ+q2stFo5SNyKZ/FCks3+GQLGOWko+rLFHLStNd9VFK83ywea03Vw4qr9QDjQSBiDAHA8BBL4Ac20EEDol+BSl46Vsj8A694m8lZaLPt7palrcm+z7WqYoZ6zVQ5a8ZVLlX1QQGkzfpn2h8IF9KH4deURcPtLbZJ0GKvr2yNfRP9wAAqGbBWAoQZkHApGBCoKoG6Cra+uCKOFAfYmQqB6WlogoxB1EHbfQtG4PA/woPDQFoPFf8oPnQDI2Bi8HgIHkfAxe0B7S5KkAMBVeV1vUwhNKwVYKfC7l/vh6wBYPt5aylUiDQMiKLRgmB4CCjA0pB4L/JUqeA8JAT8RdB4b/hpOXMaA0nbHIMv4cB8mUUGK1O8bAyNmhxhWVjdE4tN5htX7ydkERVqktTllbHHMtwDGFeqd5iyLp9qEoM0DNg8D/kg3QeCgFwVQKYDQPCf+Yflofh+DAqGFCgQCXvUHDolGiQHgIG8DSkHgv9tSp4DwkA3xF0Hhv+uk42LgUQKYtBxeWlqgGAoo4o6DBvSc8v37AKsERoFWIAGgUxXFQN0t4H4dgw2A0uHYF+AIGFet+EMERhgPxGB4X/fLZ4GERSDgVVAyBcFYjBUkVLZYHAhAGA8LAUhCB4mAbLgfNgCWDgQgDAeFgKQhA8TANlwPmwBKF0tsHAhAGA8LAUhCB4mAbLgfNgCWDgQgDAeFgKQhA8TANlwPmwBP1u1a7DMRgY+tzvSqoCxnpQIDfQIfGz2DgQgDAeFgKQhA8TANlwPmwBNsghAHDhsHgoCkQg60HhIB0uoiVACIz0GBGbBXaNn+8AALxqgSSpdhhCBjy/e9KohLWelIgt9Aj8bvgYjwR1baofW40BlgfWgXoMjwA5Svre7QeD/52eXbtW8ptKwtT8JLOjjuNB6H3VtBkIOA90RQeG/52eFHjWhb9Lb8JLOjjuNB6H3VtBkIOA90RQeG/52eFHjWha/CSzo47jQeh91bQZCDgPdEUHhv+dnhR41oW/S2/CSzo47jQeh91bQZCDgPdEUHhv+dnhR41oWvwks6OO40HofdW0GQg4D3RFB4b/nZ4UeNaFv3X9jXt/veey7VGb/eZO1R703/6az2Xdq2SvVaL2m/41k/3U0Sr5zmW8UaabiHCB+ElnRx3Gg9D7q2gyEHAe6IoPDf87PCjxrQtfhJZ0cdxoPQ+6toMhBwHuiKDw3/Ozwo8a0LfrQtWuwzEYGPrc70qqAsZ6UCA30CHxs9+ElnRx3Gg9D7q2gyEHAe6IoPDf87PCjxrQtoGUts5ntjXGcYzSroMN4B6at+7lB4P/nZ5NzYt5TNikBfsAAAMbbW9vdgAAAGxtdmhkAAAAAAAAAAAAAAAAAAAD6AAAACgAAQAAAQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAkZ0cmFrAAAAXHRraGQAAAAPAAAAAAAAAAAAAAABAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAFAAAAA8AAAAAAAkZWR0cwAAABxlbHN0AAAAAAAAAAEAAAAoAAAAAAABAAAAAAG+bWRpYQAAACBtZGhkAAAAAAAAAAAAAAAAAAAAGQAAAAFVxAAAAAAALWhkbHIAAAAAAAAAAHZpZGUAAAAAAAAAAAAAAABWaWRlb0hhbmRsZXIAAAABaW1pbmYAAAAUdm1oZAAAAAEAAAAAAAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAASlzdGJsAAAAxXN0c2QAAAAAAAAAAQAAALVtcDR2AAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAFAAPABIAAAASAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGP//AAAAX2VzZHMAAAAAA4CAgE4AAQAEgICAQCARAAAAAAYBgAAGAYAFgICALgAAAbABAAABtYkTAAABAAAAASAAxI2IAM0ChAeUQwAAAbJMYXZjNTQuMS4xMDAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAQAAAAEAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAEAAAABAAAAFHN0c3oAAAAAAAAHsAAAAAEAAAAUc3RjbwAAAAAAAAABAAAALAAAAGF1ZHRhAAAAWW1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXJhcHBsAAAAAAAAAAAAAAAALGlsc3QAAAAkqXRvbwAAABxkYXRhAAAAAQAAAABMYXZmNTQuMC4xMDA=";
-
-var ogvDataSrc = "data:video/ogg;base64,T2dnUwACAAAAAAAAAABDt3UdAAAAAG1FPOwBQGZpc2hlYWQAAwAAAAAAAAAAAAAA6AMAAAAAAAAAAAAAAAAAAOgDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPZ2dTAAIAAAAAAAAAAKK34ysAAAAAwlsClQEqgHRoZW9yYQMCAQAFAAQAAFAAADwABAAAABkAAAABAAABAAABAgAAAIDAT2dnUwAAAAAAAAAAAABDt3UdAQAAAFp3fKUBUGZpc2JvbmUALAAAAKK34ysDAAAAGQAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAYAAABDb250ZW50LVR5cGU6IHZpZGVvL3RoZW9yYQ0KT2dnUwAAAAAAAAAAAACit+MrAQAAAHoeC5AOWP///////////////5CBdGhlb3JhKwAAAFhpcGguT3JnIGxpYnRoZW9yYSAxLjEgMjAwOTA4MjIgKFRodXNuZWxkYSkBAAAAGgAAAEVOQ09ERVI9ZmZtcGVnMnRoZW9yYS0wLjI0gnRoZW9yYb7NKPe5zWsYtalJShBznOYxjFKUpCEIMYxiEIQhCEAAAAAAAAAAAAARba5TZ5LI/FYS/Hg5W2zmKvVoq1QoEykkWhD+eTmbjWZTCXiyVSmTiSSCGQh8PB2OBqNBgLxWKhQJBGIhCHw8HAyGAsFAiDgVFtrlNnksj8VhL8eDlbbOYq9WirVCgTKSRaEP55OZuNZlMJeLJVKZOJJIIZCHw8HY4Go0GAvFYqFAkEYiEIfDwcDIYCwUCIOBQLDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8MDA8SFBQVDQ0OERIVFRQODg8SFBUVFQ4QERMUFRUVEBEUFRUVFRUSExQVFRUVFRQVFRUVFRUVFRUVFRUVFRUQDAsQFBkbHA0NDhIVHBwbDg0QFBkcHBwOEBMWGx0dHBETGRwcHh4dFBgbHB0eHh0bHB0dHh4eHh0dHR0eHh4dEAsKEBgoMz0MDA4TGjo8Nw4NEBgoOUU4DhEWHTNXUD4SFiU6RG1nTRgjN0BRaHFcMUBOV2d5eGVIXF9icGRnYxMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMSEhUZGhoaGhIUFhoaGhoaFRYZGhoaGhoZGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaERIWHyQkJCQSFBgiJCQkJBYYISQkJCQkHyIkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJBESGC9jY2NjEhUaQmNjY2MYGjhjY2NjYy9CY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVEhISFRcYGRsSEhUXGBkbHBIVFxgZGxwdFRcYGRscHR0XGBkbHB0dHRgZGxwdHR0eGRscHR0dHh4bHB0dHR4eHhERERQXGhwgEREUFxocICIRFBcaHCAiJRQXGhwgIiUlFxocICIlJSUaHCAiJSUlKRwgIiUlJSkqICIlJSUpKioQEBAUGBwgKBAQFBgcICgwEBQYHCAoMEAUGBwgKDBAQBgcICgwQEBAHCAoMEBAQGAgKDBAQEBggCgwQEBAYICAB8Xlx0fV7c7D8vrrAaZid8hRvB1RN7csxFuo43wH7lEkS9wbGS+tVSNMyuxdiECcjB7R1Ml85htasNjKpSvPt3D8k7iGmZXYuxBC+RR4arUGxkvH5y7mJXR7R5Jwn3VUhBiuap91VIrsaCM5TSg9o867khwMrWY2+cP4rwvBLzt/wnHaYe0edSRMYC6tZmU1BrvhktIUf2gXoU8bHMuyNA7lB7R51ym213sFcFKowIviT/i0Wscg+4RDubX+4haRsMxZWgN05K5FD3bzqS9VSVCPM4TpWs2C43ihFdgaSByeKHu3Xf/2TG8tgpB7PAtOs7jixWYw+Ayo5GjUTSybX/1KW52RxYfB8nBNLJtHgt4DPq6BZWBFpjyZX/1KW5Ca0evOwG1EX/A9j5fQm5hOz6W2CtcCaWTXTFAeZO71VIgCTX69y9TiaXag3Os2ES1DcLKw0/xR5HfnCqkpQF0Z1kxKNfhZWLycml2keduHMQh3HubB/pbUUoCK5wxetZRZWPJF/bdyE21H2YjMOhP/pkthqKUCOEWVm68+1J5n7ahES5sOhaZPdOC5j4kc91FVIsrF8ofe+A2on/16Z4RiKQZcMU3NouO9N4YAvrWaiA6h4bfLqhTitbnnJ2iPSVRNJH+aZGE+YXzq7Ah/OncW2K59AKamlocOUYTSvaJPNcjDfMGrmG9pOV2MbgI9v3B3ECZ7RLJ51UpzMn0C1huA87Ngom9lkiaw3t5yvFZmDl1HpkuP+PiqlawgD69jAT5Nxr2i6cwiytcwHhK2KJvZI9C1m/4VUil8RvO/ydxmgsFdzdgGpMbUeyyRNOi1k5hMb6hVSMuTrOE/xuDhGExQ219l07sV2kG5fOEnkWHwgqUkbvC0P2KTytY4nHLqJDc3DMGlDbX2aXK/4UuJxizaIkZITS7a3HN5374PrVlYKIcP9xl1BUKqQ7aAml2k1o5uGcN8A+tPz1HF1YVnmE7cyx4FIiUA2ml1k0hX9HB7l4tMO+R9YrMWcf5Anub1BZXUp3Ce4jBM21l0kyhcF/vg6FGeHa345MYv4BVSciTJhj5AbuD2K0dfIXc4jKAbazaS53rv1lYqpIVr2fcgcPox4u/WVnRfJ25GGING2s2cqjKIVUtwGbRtrljLd9CQOHhewUTfiKxWk7Olr2dHyIKlLgejEbasmmdGF/dhuhVrU9xGi6Hksgm/+5Bw813T3mJyRNqIYGdYspVZFzQ6dhNLJ7H+fYWh8Q+cMbzLc/O0evM4srXGjpECaXaT2jApqM4LRavgPnH7ecDRQSErabX3zC4EcXfOVZZUpYs3UIfMsKVR+6hgFzHhvWWWl4EqZtrJpHnyeO0T2icPrqVRyyDRKmbayexv7wdolGfh1hwtsK4G5jDOIHz/lTULUM47PaBmNJm2ssmTq+ssXeHBjgij3G5P+u5QVFIGQ21TNM5aGOHbqKssQ/HiM9kvcWjdCtF6gZNMzbXFhNP2gV2FNQi+OpOR+S+3RvOBVSOr+E5hjyPrQho7/QDNEG2qRNLpHl6WVl3m4p3POFvwEWUN0ByvCQTSttdM48H7tjQWVk73qoUvhiSDbVK0mzyohbuHXofmEaK/xXYJ+Vq7tBUN6lMAdrouC3p96IS8kMzbVK0myY4f+HKdRGsrG9SlDwEfQkXsGLIbapmmcv/sA5TrqC36t4sRdjylU4JC9KwG2plM0zxuT2iFFzAPXyj9ZWRu+tx5UpFv0jn0gQrKyMF5MyaZsDbXG7/qIdp0tHG4jOQumLzBliaZttaLfZFUBSOu7FaUn/+IXETfwUj2E0o6gJ2HB/l8N7jFnzWWBESErabWPvy9bUKqS4y78CME0rbXSTNFRf8H7r1wwxQbltish5nFVIRkhKaTNtc6L3LHAh8+B2yi/tHvXG4nusVwAKMb/0/MCmoWrvASDM0mbay5YRI+7CtC96OPtxudDEyTGmbbWVRgkvR8qaiA8+rLCft7cW8H8UI3E8nzmJVSQIT3+0srHfUbgKA21ZNM8WEy+W7wbj9OuBpm21MKGWN80kaA5PZfoSqkRPLa1h31wIEjiUhcnX/e5VSWVkQnPhtqoYXrjLFpn7M8tjB17xSqfWgoA21StJpM48eSG+5A/dsGUQn8sV7impA4dQjxPyrsBfHd8tUGBIJWkxtrnljE3eu/xTUO/nVsA9I4uVlZ5uQvy9IwYjbWUmaZ5XE9HAWVkXUKmoI3y4vDKZpnKNtccJHK2iA83ej+fvgI3KR9P6qpG/kBCUdxHFisLkq8aZttTCZlj/b0G8XoLX/3fHhZWCVcMsWmZtqmYXz0cpOiBHCqpKUZu76iICRxYVuSULpmF/421MsWmfyhbP4ew1FVKAjFlY437JXImUTm2r/4ZYtMy61hf16RPJIRA8tU1BDc5/JzAkEzTM21lyx7sK9wojRX/OHXoOv05IDbUymaZyscL7qlMA8c/CiK3csceqzuOEU1EPpbz4QEahIShpm21MJmWN924f98WKyf51EEYBli0zNtUzC+6X9P9ysrU1CHyA3RJFFr1w67HpyULT+YMsWmZtquYXz97oKil44sI1bpL8hRSDeMkhiIBwOgxwZ5Fs6+5M+NdH+3Kjv0sreSqqRvGSQxEA4HQY4M8i2dfcmfGuj/blR36WVvJVVI3jJIYiAcDoMcGeRbOvuTPjXR/tyo79LK3kqqkVUnCfqAES8EzTM21lykY4Q+LKxby+9F3ZHR/uC2OGpS9cv6BZXAebhckMGIymaZm2st8/B38i6A/n58pVLKwfURet4UBwSF6UaZttSZljhd2jW9BZWcrX0/hG4Sdt/SBCdH6UMJmWK80zba3URKaik8iB9PR2459CuyOAbi0/GWLTMmYXm2t0vUkNQhRPVldKpAN5HgHyZfdOtGuj/YxwZ5S8u3CjqMgQoyQJRdawvJlE530/+sVg21c8GWLTPf3yJVSVUoCMWVjjfslciZRObav/hli0zLrWF/XpE8khT2dnUwAEAAAAAAAAAABDt3UdAgAAAAzIIuQBAE9nZ1MABEAAAAAAAAAAorfjKwIAAABgTJAeBf////+/IK2oPwLwetDyEoOnddpgLM7J5tdTLMgoKCgs2quQe7o7SkFBQfQK1d3nTvIG8WYJg+kQTYyKcCBTI2uld4Ck3ITAiUxzwCDzbvEz4RL4jH2GES+Ix2gjjoZkfroYD2Rxe50JehL0UdqOhDasSshteOirUpDV6cdCD6ZJksRwtMAehrVhPC2k8aZU2c9cac+Z9PmWWWX4+Pj4BEssvCb4TfCZNG9wSOUm6QGyfTX2kmypyN8xrVMPuq146O3o6OjorWtdevXrGK1qWvX08a6Rq0xLLxJJJTaDmSCHcNKfdSi8+/01vmG83m83ns7OzsErzebyPYtBJ0iEFRa8Nk7BZXXvaD9HsioatlKUtt6FxDflKUpxFWLa06Gy9Fa73KyurjJRShhHP3rKPc1/8e9M4svw7z9/y5hmd6tC/+c2BGWkiRIkSMOWLESxaepEN5HCA8fbnt2c+oiWh3nDTVDj5GpecOZ6Pej2HglzRu77Ha7NevXrw9mr17Ge0nSP3nJ+/u8QhEvP/jNd8EFWSIRATu7oooou7uijwzeQQSuISlxl4fNRTj4fl3hrIGCibpjzMyqyFWQqyFWQBMyJVkKPwSJe+CRxuoEF/gEU2CHC4E9tYgQEIgLbW21ttbbW21ttbbW3VRNfeEUjw5p+43Jszx9/+J9Xq/cPHkNoGheXKleIvTLu7iOchCVRx4+8YZD/8eO7wQfAz3YR//ArgZPYDA4O/j0JZ8SBCyNGQJAoyBIGM3Nszg65/dg9KU0ZAssfyut/18FfOYHejZoiN64XH3AV8+A+MZAbifeO46k45f/YwcgIrj/v0lKe/O7777/urfwDuRL4vnLC2W8VNKmlTXI85zhb9Tzg5Pq3b4MHGJysA0vsJbIsiyLIsEXpf8Fvh9ve5rMuDmsFkgjCv6z0V/RCArnWZw2pL3cs2uKgHydecWhDe3OxQXkRfRz3haf8V7+0/u7FiQDyfSCDxnf/uIhzK8RYGDCXYRMYqVpiJEi6iqzlnq91PbMvN7rqyqfI2QlKUpAgQIcDeBvA3afsV8/MqBxcDH6z8DKVq+fDeHyLb9bk1SlLLSZV5sj6vR9c+ZoSzmUe7nFIY77Io1uY7TGlp67W1xSRjyffmuz+ZZnIo6iK81o5jPqjLad2pJVNlxcrFNTU1NxMGZmYZLw9FOO1MMyzMZOXW2i5f+SZOTWvXrxbvWtF9F/qpM8k7VWZ1srpVdmc/rNt5671q/4oaPLioDn63vKe+3TsR1QdT3cbbX29dJhFWxGfPji8uow/RvEdxN26QXd3d3dmltxmvn9xX41q7lJ+EyZMmTJk5d7e2lt4T80idGzp5p4ZOwcwt9MfSg2px6rrOjC7dunTLPnPm37py9tZjaU10a2lujlPd5ZYZbWZmZmYa7t76epZjI6IyFSpUiRI6tO81MJ+FSshXxUNo2qCYteb6DTfQ7eWHcYqrx8q3N+WmphpSJJJJM/j1au8t2/m25K9evXr169fcx23mLqG6yrVvctNSdG9PTPz32j10DtUeJJJCiPs2L3slpLcg3LLLJJJQaTfR9IalPOLMvdptttts9C1Q35jwWm306Lp06dOnTp0aWtuFpwSSSSHPcIguQA=";
-
 var testInfo = [
     { element: "video", typeArray: ["video/mp4", "video/ogg"], srcArray: ["content/test.mp4", "content/test.ogv"], description: "Test video with ['video/mp4', 'video/ogg']" },
     { element: "video", typeArray: ["video/ogg", "video/mp4"], srcArray: ["content/test.ogv", "content/test.mp4"], description: "Test video with ['video/ogg', 'video/mp4']" },
     { element: "audio", typeArray: ["audio/wav", "audio/ogg"], srcArray: ["content/test.wav", "content/test.oga"], description: "Test audio with ['audio/wav', 'audio/ogg']" },
     { element: "audio", typeArray: ["audio/ogg", "audio/wav"], srcArray: ["content/test.oga", "content/test.wav"], description: "Test audio with ['audio/ogg', 'audio/wav']" },
-    { element: "video", srcArray: [mp4DataSrc, ogvDataSrc], description: "Test video with ['data:video/mp4;base64', 'data:video/ogg;base64']" },
-    { element: "video", srcArray: [ogvDataSrc, mp4DataSrc], description: "Test video with ['data:video/ogg;base64', 'data:video/mp4;base64']" },
     { element: "audio", typeArray: ["audio/mp4", "audio/ogg"], srcArray: ["content/test.m4a", "content/test.oga"], description: "Test audio with ['audio/mp4', \"audio/ogg\"]" },
     { element: "audio", typeArray: ["audio/ogg", "audio/mp4"], srcArray: ["content/test.oga", "content/test.m4a"], description: "Test audio with ['audio/ogg', \"audio/mp4\"]" },
 ];
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/webnn/elementwise_unary.https.any-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/webnn/elementwise_unary.https.any-expected.txt
index 5aec7b3..0e50eae 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/webnn/elementwise_unary.https.any-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/webnn/elementwise_unary.https.any-expected.txt
@@ -20,25 +20,25 @@
 [FAIL] ceil float32 5D tensor / async
   promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] cos float32 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] cos float32 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] cos float32 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] cos float32 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] cos float32 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] exp float32 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] exp float32 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] exp float32 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] exp float32 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] exp float32 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] floor float32 1D tensor / async
   promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] floor float32 2D tensor / async
@@ -50,15 +50,15 @@
 [FAIL] floor float32 5D tensor / async
   promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] log float32 positive 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] log float32 positive 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] log float32 positive 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] log float32 positive 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] log float32 positive 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] neg float32 1D tensor / async
   promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] neg float32 2D tensor / async
@@ -70,24 +70,24 @@
 [FAIL] neg float32 5D tensor / async
   promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] sin float32 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] sin float32 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] sin float32 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] sin float32 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] sin float32 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] tan float32 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] tan float32 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] tan float32 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] tan float32 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [FAIL] tan float32 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/webnn/elementwise_unary.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/webnn/elementwise_unary.https.any.worker-expected.txt
index 9266a110..6d7bb7c7 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/webnn/elementwise_unary.https.any.worker-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/webnn/elementwise_unary.https.any.worker-expected.txt
@@ -21,25 +21,25 @@
 [FAIL] ceil float32 5D tensor / sync
   Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] cos float32 1D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] cos float32 2D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] cos float32 3D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] cos float32 4D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] cos float32 5D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] exp float32 1D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] exp float32 2D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] exp float32 3D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] exp float32 4D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] exp float32 5D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] floor float32 1D tensor / sync
   Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] floor float32 2D tensor / sync
@@ -51,15 +51,15 @@
 [FAIL] floor float32 5D tensor / sync
   Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] log float32 positive 1D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] log float32 positive 2D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] log float32 positive 3D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] log float32 positive 4D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] log float32 positive 5D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] neg float32 1D tensor / sync
   Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] neg float32 2D tensor / sync
@@ -71,25 +71,25 @@
 [FAIL] neg float32 5D tensor / sync
   Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] sin float32 1D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] sin float32 2D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] sin float32 3D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] sin float32 4D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] sin float32 5D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] tan float32 1D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] tan float32 2D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] tan float32 3D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] tan float32 4D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] tan float32 5D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] abs float32 1D tensor / async
   promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] abs float32 2D tensor / async
@@ -111,25 +111,25 @@
 [FAIL] ceil float32 5D tensor / async
   promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] cos float32 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] cos float32 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] cos float32 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] cos float32 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] cos float32 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] exp float32 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] exp float32 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] exp float32 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] exp float32 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] exp float32 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] floor float32 1D tensor / async
   promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] floor float32 2D tensor / async
@@ -141,15 +141,15 @@
 [FAIL] floor float32 5D tensor / async
   promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] log float32 positive 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] log float32 positive 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] log float32 positive 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] log float32 positive 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] log float32 positive 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] neg float32 1D tensor / async
   promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] neg float32 2D tensor / async
@@ -161,24 +161,24 @@
 [FAIL] neg float32 5D tensor / async
   promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] sin float32 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] sin float32 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] sin float32 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] sin float32 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] sin float32 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] tan float32 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] tan float32 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] tan float32 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] tan float32 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] tan float32 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/webnn/idlharness.https.any-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/webnn/idlharness.https.any-expected.txt
index cc98dde8..f3ec31e 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/webnn/idlharness.https.any-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/webnn/idlharness.https.any-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 408 tests; 326 PASS, 82 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 408 tests; 346 PASS, 62 FAIL, 0 TIMEOUT, 0 NOTRUN.
 [FAIL] idl_test setup
   promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
 [PASS] idl_test validation
@@ -219,18 +219,13 @@
 [PASS] MLGraphBuilder interface: operation pow(MLOperand, MLOperand)
 [PASS] MLGraphBuilder interface: operation abs(MLOperand)
 [PASS] MLGraphBuilder interface: operation ceil(MLOperand)
-[FAIL] MLGraphBuilder interface: operation cos(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "cos" missing
-[FAIL] MLGraphBuilder interface: operation exp(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "exp" missing
+[PASS] MLGraphBuilder interface: operation cos(MLOperand)
+[PASS] MLGraphBuilder interface: operation exp(MLOperand)
 [PASS] MLGraphBuilder interface: operation floor(MLOperand)
-[FAIL] MLGraphBuilder interface: operation log(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "log" missing
+[PASS] MLGraphBuilder interface: operation log(MLOperand)
 [PASS] MLGraphBuilder interface: operation neg(MLOperand)
-[FAIL] MLGraphBuilder interface: operation sin(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "sin" missing
-[FAIL] MLGraphBuilder interface: operation tan(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "tan" missing
+[PASS] MLGraphBuilder interface: operation sin(MLOperand)
+[PASS] MLGraphBuilder interface: operation tan(MLOperand)
 [PASS] MLGraphBuilder interface: operation elu(MLOperand, optional MLEluOptions)
 [PASS] MLGraphBuilder interface: operation elu(optional MLEluOptions)
 [PASS] MLGraphBuilder interface: operation gemm(MLOperand, MLOperand, optional MLGemmOptions)
@@ -288,10 +283,8 @@
   assert_own_property: interface prototype object missing non-static operation expected property "softplus" missing
 [FAIL] MLGraphBuilder interface: operation softplus(optional MLSoftplusOptions)
   assert_own_property: interface prototype object missing non-static operation expected property "softplus" missing
-[FAIL] MLGraphBuilder interface: operation softsign(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "softsign" missing
-[FAIL] MLGraphBuilder interface: operation softsign()
-  assert_own_property: interface prototype object missing non-static operation expected property "softsign" missing
+[PASS] MLGraphBuilder interface: operation softsign(MLOperand)
+[PASS] MLGraphBuilder interface: operation softsign()
 [PASS] MLGraphBuilder interface: operation split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions)
 [FAIL] MLGraphBuilder interface: operation squeeze(MLOperand, optional MLSqueezeOptions)
   assert_own_property: interface prototype object missing non-static operation expected property "squeeze" missing
@@ -341,30 +334,20 @@
 [PASS] MLGraphBuilder interface: calling abs(MLOperand) on builder with too few arguments must throw TypeError
 [PASS] MLGraphBuilder interface: builder must inherit property "ceil(MLOperand)" with the proper type
 [PASS] MLGraphBuilder interface: calling ceil(MLOperand) on builder with too few arguments must throw TypeError
-[FAIL] MLGraphBuilder interface: builder must inherit property "cos(MLOperand)" with the proper type
-  assert_inherits: property "cos" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling cos(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "cos" not found in prototype chain
-[FAIL] MLGraphBuilder interface: builder must inherit property "exp(MLOperand)" with the proper type
-  assert_inherits: property "exp" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling exp(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "exp" not found in prototype chain
+[PASS] MLGraphBuilder interface: builder must inherit property "cos(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling cos(MLOperand) on builder with too few arguments must throw TypeError
+[PASS] MLGraphBuilder interface: builder must inherit property "exp(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling exp(MLOperand) on builder with too few arguments must throw TypeError
 [PASS] MLGraphBuilder interface: builder must inherit property "floor(MLOperand)" with the proper type
 [PASS] MLGraphBuilder interface: calling floor(MLOperand) on builder with too few arguments must throw TypeError
-[FAIL] MLGraphBuilder interface: builder must inherit property "log(MLOperand)" with the proper type
-  assert_inherits: property "log" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling log(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "log" not found in prototype chain
+[PASS] MLGraphBuilder interface: builder must inherit property "log(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling log(MLOperand) on builder with too few arguments must throw TypeError
 [PASS] MLGraphBuilder interface: builder must inherit property "neg(MLOperand)" with the proper type
 [PASS] MLGraphBuilder interface: calling neg(MLOperand) on builder with too few arguments must throw TypeError
-[FAIL] MLGraphBuilder interface: builder must inherit property "sin(MLOperand)" with the proper type
-  assert_inherits: property "sin" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling sin(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "sin" not found in prototype chain
-[FAIL] MLGraphBuilder interface: builder must inherit property "tan(MLOperand)" with the proper type
-  assert_inherits: property "tan" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling tan(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "tan" not found in prototype chain
+[PASS] MLGraphBuilder interface: builder must inherit property "sin(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling sin(MLOperand) on builder with too few arguments must throw TypeError
+[PASS] MLGraphBuilder interface: builder must inherit property "tan(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling tan(MLOperand) on builder with too few arguments must throw TypeError
 [PASS] MLGraphBuilder interface: builder must inherit property "elu(MLOperand, optional MLEluOptions)" with the proper type
 [PASS] MLGraphBuilder interface: calling elu(MLOperand, optional MLEluOptions) on builder with too few arguments must throw TypeError
 [PASS] MLGraphBuilder interface: builder must inherit property "elu(optional MLEluOptions)" with the proper type
@@ -471,12 +454,9 @@
   assert_inherits: property "softplus" not found in prototype chain
 [FAIL] MLGraphBuilder interface: calling softplus(optional MLSoftplusOptions) on builder with too few arguments must throw TypeError
   assert_inherits: property "softplus" not found in prototype chain
-[FAIL] MLGraphBuilder interface: builder must inherit property "softsign(MLOperand)" with the proper type
-  assert_inherits: property "softsign" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling softsign(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "softsign" not found in prototype chain
-[FAIL] MLGraphBuilder interface: builder must inherit property "softsign()" with the proper type
-  assert_inherits: property "softsign" not found in prototype chain
+[PASS] MLGraphBuilder interface: builder must inherit property "softsign(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling softsign(MLOperand) on builder with too few arguments must throw TypeError
+[PASS] MLGraphBuilder interface: builder must inherit property "softsign()" with the proper type
 [PASS] MLGraphBuilder interface: builder must inherit property "split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions)" with the proper type
 [PASS] MLGraphBuilder interface: calling split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions) on builder with too few arguments must throw TypeError
 [FAIL] MLGraphBuilder interface: builder must inherit property "squeeze(MLOperand, optional MLSqueezeOptions)" with the proper type
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/webnn/idlharness.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/webnn/idlharness.https.any.worker-expected.txt
index 98cf450..f375552 100644
--- a/third_party/blink/web_tests/platform/mac/external/wpt/webnn/idlharness.https.any.worker-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/webnn/idlharness.https.any.worker-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 414 tests; 325 PASS, 89 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 414 tests; 345 PASS, 69 FAIL, 0 TIMEOUT, 0 NOTRUN.
 [FAIL] idl_test setup
   promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented"
 [PASS] idl_test validation
@@ -229,18 +229,13 @@
 [PASS] MLGraphBuilder interface: operation pow(MLOperand, MLOperand)
 [PASS] MLGraphBuilder interface: operation abs(MLOperand)
 [PASS] MLGraphBuilder interface: operation ceil(MLOperand)
-[FAIL] MLGraphBuilder interface: operation cos(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "cos" missing
-[FAIL] MLGraphBuilder interface: operation exp(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "exp" missing
+[PASS] MLGraphBuilder interface: operation cos(MLOperand)
+[PASS] MLGraphBuilder interface: operation exp(MLOperand)
 [PASS] MLGraphBuilder interface: operation floor(MLOperand)
-[FAIL] MLGraphBuilder interface: operation log(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "log" missing
+[PASS] MLGraphBuilder interface: operation log(MLOperand)
 [PASS] MLGraphBuilder interface: operation neg(MLOperand)
-[FAIL] MLGraphBuilder interface: operation sin(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "sin" missing
-[FAIL] MLGraphBuilder interface: operation tan(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "tan" missing
+[PASS] MLGraphBuilder interface: operation sin(MLOperand)
+[PASS] MLGraphBuilder interface: operation tan(MLOperand)
 [PASS] MLGraphBuilder interface: operation elu(MLOperand, optional MLEluOptions)
 [PASS] MLGraphBuilder interface: operation elu(optional MLEluOptions)
 [PASS] MLGraphBuilder interface: operation gemm(MLOperand, MLOperand, optional MLGemmOptions)
@@ -298,10 +293,8 @@
   assert_own_property: interface prototype object missing non-static operation expected property "softplus" missing
 [FAIL] MLGraphBuilder interface: operation softplus(optional MLSoftplusOptions)
   assert_own_property: interface prototype object missing non-static operation expected property "softplus" missing
-[FAIL] MLGraphBuilder interface: operation softsign(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "softsign" missing
-[FAIL] MLGraphBuilder interface: operation softsign()
-  assert_own_property: interface prototype object missing non-static operation expected property "softsign" missing
+[PASS] MLGraphBuilder interface: operation softsign(MLOperand)
+[PASS] MLGraphBuilder interface: operation softsign()
 [PASS] MLGraphBuilder interface: operation split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions)
 [FAIL] MLGraphBuilder interface: operation squeeze(MLOperand, optional MLSqueezeOptions)
   assert_own_property: interface prototype object missing non-static operation expected property "squeeze" missing
@@ -354,30 +347,20 @@
 [PASS] MLGraphBuilder interface: calling abs(MLOperand) on builder with too few arguments must throw TypeError
 [PASS] MLGraphBuilder interface: builder must inherit property "ceil(MLOperand)" with the proper type
 [PASS] MLGraphBuilder interface: calling ceil(MLOperand) on builder with too few arguments must throw TypeError
-[FAIL] MLGraphBuilder interface: builder must inherit property "cos(MLOperand)" with the proper type
-  assert_inherits: property "cos" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling cos(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "cos" not found in prototype chain
-[FAIL] MLGraphBuilder interface: builder must inherit property "exp(MLOperand)" with the proper type
-  assert_inherits: property "exp" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling exp(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "exp" not found in prototype chain
+[PASS] MLGraphBuilder interface: builder must inherit property "cos(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling cos(MLOperand) on builder with too few arguments must throw TypeError
+[PASS] MLGraphBuilder interface: builder must inherit property "exp(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling exp(MLOperand) on builder with too few arguments must throw TypeError
 [PASS] MLGraphBuilder interface: builder must inherit property "floor(MLOperand)" with the proper type
 [PASS] MLGraphBuilder interface: calling floor(MLOperand) on builder with too few arguments must throw TypeError
-[FAIL] MLGraphBuilder interface: builder must inherit property "log(MLOperand)" with the proper type
-  assert_inherits: property "log" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling log(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "log" not found in prototype chain
+[PASS] MLGraphBuilder interface: builder must inherit property "log(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling log(MLOperand) on builder with too few arguments must throw TypeError
 [PASS] MLGraphBuilder interface: builder must inherit property "neg(MLOperand)" with the proper type
 [PASS] MLGraphBuilder interface: calling neg(MLOperand) on builder with too few arguments must throw TypeError
-[FAIL] MLGraphBuilder interface: builder must inherit property "sin(MLOperand)" with the proper type
-  assert_inherits: property "sin" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling sin(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "sin" not found in prototype chain
-[FAIL] MLGraphBuilder interface: builder must inherit property "tan(MLOperand)" with the proper type
-  assert_inherits: property "tan" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling tan(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "tan" not found in prototype chain
+[PASS] MLGraphBuilder interface: builder must inherit property "sin(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling sin(MLOperand) on builder with too few arguments must throw TypeError
+[PASS] MLGraphBuilder interface: builder must inherit property "tan(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling tan(MLOperand) on builder with too few arguments must throw TypeError
 [PASS] MLGraphBuilder interface: builder must inherit property "elu(MLOperand, optional MLEluOptions)" with the proper type
 [PASS] MLGraphBuilder interface: calling elu(MLOperand, optional MLEluOptions) on builder with too few arguments must throw TypeError
 [PASS] MLGraphBuilder interface: builder must inherit property "elu(optional MLEluOptions)" with the proper type
@@ -484,12 +467,9 @@
   assert_inherits: property "softplus" not found in prototype chain
 [FAIL] MLGraphBuilder interface: calling softplus(optional MLSoftplusOptions) on builder with too few arguments must throw TypeError
   assert_inherits: property "softplus" not found in prototype chain
-[FAIL] MLGraphBuilder interface: builder must inherit property "softsign(MLOperand)" with the proper type
-  assert_inherits: property "softsign" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling softsign(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "softsign" not found in prototype chain
-[FAIL] MLGraphBuilder interface: builder must inherit property "softsign()" with the proper type
-  assert_inherits: property "softsign" not found in prototype chain
+[PASS] MLGraphBuilder interface: builder must inherit property "softsign(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling softsign(MLOperand) on builder with too few arguments must throw TypeError
+[PASS] MLGraphBuilder interface: builder must inherit property "softsign()" with the proper type
 [PASS] MLGraphBuilder interface: builder must inherit property "split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions)" with the proper type
 [PASS] MLGraphBuilder interface: calling split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions) on builder with too few arguments must throw TypeError
 [FAIL] MLGraphBuilder interface: builder must inherit property "squeeze(MLOperand, optional MLSqueezeOptions)" with the proper type
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/webnn/softsign.https.any-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/webnn/softsign.https.any-expected.txt
new file mode 100644
index 0000000..7c8156f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/webnn/softsign.https.any-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+[FAIL] softsign positive float32 1D tensor / async
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
+[FAIL] softsign negative float32 1D tensor / async
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
+[FAIL] softsign float32 2D tensor / async
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
+[FAIL] softsign float32 3D tensor / async
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
+[FAIL] softsign float32 4D tensor / async
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
+[FAIL] softsign float32 5D tensor / async
+  promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/webnn/softsign.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/webnn/softsign.https.any.worker-expected.txt
similarity index 61%
rename from third_party/blink/web_tests/external/wpt/webnn/softsign.https.any.worker-expected.txt
rename to third_party/blink/web_tests/platform/mac/external/wpt/webnn/softsign.https.any.worker-expected.txt
index ddcea72..a2b138b 100644
--- a/third_party/blink/web_tests/external/wpt/webnn/softsign.https.any.worker-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/webnn/softsign.https.any.worker-expected.txt
@@ -1,27 +1,27 @@
 This is a testharness.js-based test.
 [FAIL] softsign positive float32 1D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] softsign negative float32 1D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] softsign float32 2D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] softsign float32 3D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] softsign float32 4D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] softsign float32 5D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented
 [FAIL] softsign positive float32 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] softsign negative float32 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] softsign float32 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] softsign float32 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] softsign float32 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] softsign float32 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/elementwise_unary.https.any-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/webnn/elementwise_unary.https.any-expected.txt
index 8097e0e7..aa40b04 100644
--- a/third_party/blink/web_tests/platform/win/external/wpt/webnn/elementwise_unary.https.any-expected.txt
+++ b/third_party/blink/web_tests/platform/win/external/wpt/webnn/elementwise_unary.https.any-expected.txt
@@ -10,64 +10,64 @@
 [PASS] ceil float32 4D tensor / async
 [PASS] ceil float32 5D tensor / async
 [FAIL] cos float32 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (cos) is not supported."
 [FAIL] cos float32 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (cos) is not supported."
 [FAIL] cos float32 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (cos) is not supported."
 [FAIL] cos float32 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (cos) is not supported."
 [FAIL] cos float32 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (cos) is not supported."
 [FAIL] exp float32 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (exp) is not supported."
 [FAIL] exp float32 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (exp) is not supported."
 [FAIL] exp float32 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (exp) is not supported."
 [FAIL] exp float32 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (exp) is not supported."
 [FAIL] exp float32 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (exp) is not supported."
 [PASS] floor float32 1D tensor / async
 [PASS] floor float32 2D tensor / async
 [PASS] floor float32 3D tensor / async
 [PASS] floor float32 4D tensor / async
 [PASS] floor float32 5D tensor / async
 [FAIL] log float32 positive 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (log) is not supported."
 [FAIL] log float32 positive 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (log) is not supported."
 [FAIL] log float32 positive 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (log) is not supported."
 [FAIL] log float32 positive 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (log) is not supported."
 [FAIL] log float32 positive 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (log) is not supported."
 [PASS] neg float32 1D tensor / async
 [PASS] neg float32 2D tensor / async
 [PASS] neg float32 3D tensor / async
 [PASS] neg float32 4D tensor / async
 [PASS] neg float32 5D tensor / async
 [FAIL] sin float32 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (sin) is not supported."
 [FAIL] sin float32 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (sin) is not supported."
 [FAIL] sin float32 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (sin) is not supported."
 [FAIL] sin float32 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (sin) is not supported."
 [FAIL] sin float32 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (sin) is not supported."
 [FAIL] tan float32 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (tan) is not supported."
 [FAIL] tan float32 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (tan) is not supported."
 [FAIL] tan float32 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (tan) is not supported."
 [FAIL] tan float32 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (tan) is not supported."
 [FAIL] tan float32 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (tan) is not supported."
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/elementwise_unary.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/webnn/elementwise_unary.https.any.worker-expected.txt
index affaf5ab..148af10 100644
--- a/third_party/blink/web_tests/platform/win/external/wpt/webnn/elementwise_unary.https.any.worker-expected.txt
+++ b/third_party/blink/web_tests/platform/win/external/wpt/webnn/elementwise_unary.https.any.worker-expected.txt
@@ -11,65 +11,65 @@
 [PASS] ceil float32 4D tensor / sync
 [PASS] ceil float32 5D tensor / sync
 [FAIL] cos float32 1D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (cos) is not supported.
 [FAIL] cos float32 2D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (cos) is not supported.
 [FAIL] cos float32 3D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (cos) is not supported.
 [FAIL] cos float32 4D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (cos) is not supported.
 [FAIL] cos float32 5D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (cos) is not supported.
 [FAIL] exp float32 1D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (exp) is not supported.
 [FAIL] exp float32 2D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (exp) is not supported.
 [FAIL] exp float32 3D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (exp) is not supported.
 [FAIL] exp float32 4D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (exp) is not supported.
 [FAIL] exp float32 5D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (exp) is not supported.
 [PASS] floor float32 1D tensor / sync
 [PASS] floor float32 2D tensor / sync
 [PASS] floor float32 3D tensor / sync
 [PASS] floor float32 4D tensor / sync
 [PASS] floor float32 5D tensor / sync
 [FAIL] log float32 positive 1D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (log) is not supported.
 [FAIL] log float32 positive 2D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (log) is not supported.
 [FAIL] log float32 positive 3D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (log) is not supported.
 [FAIL] log float32 positive 4D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (log) is not supported.
 [FAIL] log float32 positive 5D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (log) is not supported.
 [PASS] neg float32 1D tensor / sync
 [PASS] neg float32 2D tensor / sync
 [PASS] neg float32 3D tensor / sync
 [PASS] neg float32 4D tensor / sync
 [PASS] neg float32 5D tensor / sync
 [FAIL] sin float32 1D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (sin) is not supported.
 [FAIL] sin float32 2D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (sin) is not supported.
 [FAIL] sin float32 3D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (sin) is not supported.
 [FAIL] sin float32 4D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (sin) is not supported.
 [FAIL] sin float32 5D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (sin) is not supported.
 [FAIL] tan float32 1D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (tan) is not supported.
 [FAIL] tan float32 2D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (tan) is not supported.
 [FAIL] tan float32 3D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (tan) is not supported.
 [FAIL] tan float32 4D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (tan) is not supported.
 [FAIL] tan float32 5D tensor / sync
-  builder[operationName] is not a function
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (tan) is not supported.
 [FAIL] abs float32 1D tensor / async
   promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] abs float32 2D tensor / async
@@ -91,25 +91,25 @@
 [FAIL] ceil float32 5D tensor / async
   promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] cos float32 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] cos float32 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] cos float32 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] cos float32 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] cos float32 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] exp float32 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] exp float32 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] exp float32 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] exp float32 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] exp float32 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] floor float32 1D tensor / async
   promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] floor float32 2D tensor / async
@@ -121,15 +121,15 @@
 [FAIL] floor float32 5D tensor / async
   promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] log float32 positive 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] log float32 positive 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] log float32 positive 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] log float32 positive 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] log float32 positive 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] neg float32 1D tensor / async
   promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] neg float32 2D tensor / async
@@ -141,24 +141,24 @@
 [FAIL] neg float32 5D tensor / async
   promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] sin float32 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] sin float32 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] sin float32 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] sin float32 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] sin float32 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] tan float32 1D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] tan float32 2D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] tan float32 3D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] tan float32 4D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 [FAIL] tan float32 5D tensor / async
-  promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function"
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/idlharness.https.any-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/webnn/idlharness.https.any-expected.txt
index 3e42bddf..442d0a8 100644
--- a/third_party/blink/web_tests/platform/win/external/wpt/webnn/idlharness.https.any-expected.txt
+++ b/third_party/blink/web_tests/platform/win/external/wpt/webnn/idlharness.https.any-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 408 tests; 326 PASS, 82 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 408 tests; 346 PASS, 62 FAIL, 0 TIMEOUT, 0 NOTRUN.
 [FAIL] idl_test setup
   promise_test: Unhandled rejection with value: object "NotSupportedError: The input layout nchw is not supported."
 [PASS] idl_test validation
@@ -219,18 +219,13 @@
 [PASS] MLGraphBuilder interface: operation pow(MLOperand, MLOperand)
 [PASS] MLGraphBuilder interface: operation abs(MLOperand)
 [PASS] MLGraphBuilder interface: operation ceil(MLOperand)
-[FAIL] MLGraphBuilder interface: operation cos(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "cos" missing
-[FAIL] MLGraphBuilder interface: operation exp(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "exp" missing
+[PASS] MLGraphBuilder interface: operation cos(MLOperand)
+[PASS] MLGraphBuilder interface: operation exp(MLOperand)
 [PASS] MLGraphBuilder interface: operation floor(MLOperand)
-[FAIL] MLGraphBuilder interface: operation log(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "log" missing
+[PASS] MLGraphBuilder interface: operation log(MLOperand)
 [PASS] MLGraphBuilder interface: operation neg(MLOperand)
-[FAIL] MLGraphBuilder interface: operation sin(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "sin" missing
-[FAIL] MLGraphBuilder interface: operation tan(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "tan" missing
+[PASS] MLGraphBuilder interface: operation sin(MLOperand)
+[PASS] MLGraphBuilder interface: operation tan(MLOperand)
 [PASS] MLGraphBuilder interface: operation elu(MLOperand, optional MLEluOptions)
 [PASS] MLGraphBuilder interface: operation elu(optional MLEluOptions)
 [PASS] MLGraphBuilder interface: operation gemm(MLOperand, MLOperand, optional MLGemmOptions)
@@ -288,10 +283,8 @@
   assert_own_property: interface prototype object missing non-static operation expected property "softplus" missing
 [FAIL] MLGraphBuilder interface: operation softplus(optional MLSoftplusOptions)
   assert_own_property: interface prototype object missing non-static operation expected property "softplus" missing
-[FAIL] MLGraphBuilder interface: operation softsign(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "softsign" missing
-[FAIL] MLGraphBuilder interface: operation softsign()
-  assert_own_property: interface prototype object missing non-static operation expected property "softsign" missing
+[PASS] MLGraphBuilder interface: operation softsign(MLOperand)
+[PASS] MLGraphBuilder interface: operation softsign()
 [PASS] MLGraphBuilder interface: operation split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions)
 [FAIL] MLGraphBuilder interface: operation squeeze(MLOperand, optional MLSqueezeOptions)
   assert_own_property: interface prototype object missing non-static operation expected property "squeeze" missing
@@ -341,30 +334,20 @@
 [PASS] MLGraphBuilder interface: calling abs(MLOperand) on builder with too few arguments must throw TypeError
 [PASS] MLGraphBuilder interface: builder must inherit property "ceil(MLOperand)" with the proper type
 [PASS] MLGraphBuilder interface: calling ceil(MLOperand) on builder with too few arguments must throw TypeError
-[FAIL] MLGraphBuilder interface: builder must inherit property "cos(MLOperand)" with the proper type
-  assert_inherits: property "cos" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling cos(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "cos" not found in prototype chain
-[FAIL] MLGraphBuilder interface: builder must inherit property "exp(MLOperand)" with the proper type
-  assert_inherits: property "exp" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling exp(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "exp" not found in prototype chain
+[PASS] MLGraphBuilder interface: builder must inherit property "cos(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling cos(MLOperand) on builder with too few arguments must throw TypeError
+[PASS] MLGraphBuilder interface: builder must inherit property "exp(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling exp(MLOperand) on builder with too few arguments must throw TypeError
 [PASS] MLGraphBuilder interface: builder must inherit property "floor(MLOperand)" with the proper type
 [PASS] MLGraphBuilder interface: calling floor(MLOperand) on builder with too few arguments must throw TypeError
-[FAIL] MLGraphBuilder interface: builder must inherit property "log(MLOperand)" with the proper type
-  assert_inherits: property "log" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling log(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "log" not found in prototype chain
+[PASS] MLGraphBuilder interface: builder must inherit property "log(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling log(MLOperand) on builder with too few arguments must throw TypeError
 [PASS] MLGraphBuilder interface: builder must inherit property "neg(MLOperand)" with the proper type
 [PASS] MLGraphBuilder interface: calling neg(MLOperand) on builder with too few arguments must throw TypeError
-[FAIL] MLGraphBuilder interface: builder must inherit property "sin(MLOperand)" with the proper type
-  assert_inherits: property "sin" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling sin(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "sin" not found in prototype chain
-[FAIL] MLGraphBuilder interface: builder must inherit property "tan(MLOperand)" with the proper type
-  assert_inherits: property "tan" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling tan(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "tan" not found in prototype chain
+[PASS] MLGraphBuilder interface: builder must inherit property "sin(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling sin(MLOperand) on builder with too few arguments must throw TypeError
+[PASS] MLGraphBuilder interface: builder must inherit property "tan(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling tan(MLOperand) on builder with too few arguments must throw TypeError
 [PASS] MLGraphBuilder interface: builder must inherit property "elu(MLOperand, optional MLEluOptions)" with the proper type
 [PASS] MLGraphBuilder interface: calling elu(MLOperand, optional MLEluOptions) on builder with too few arguments must throw TypeError
 [PASS] MLGraphBuilder interface: builder must inherit property "elu(optional MLEluOptions)" with the proper type
@@ -471,12 +454,9 @@
   assert_inherits: property "softplus" not found in prototype chain
 [FAIL] MLGraphBuilder interface: calling softplus(optional MLSoftplusOptions) on builder with too few arguments must throw TypeError
   assert_inherits: property "softplus" not found in prototype chain
-[FAIL] MLGraphBuilder interface: builder must inherit property "softsign(MLOperand)" with the proper type
-  assert_inherits: property "softsign" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling softsign(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "softsign" not found in prototype chain
-[FAIL] MLGraphBuilder interface: builder must inherit property "softsign()" with the proper type
-  assert_inherits: property "softsign" not found in prototype chain
+[PASS] MLGraphBuilder interface: builder must inherit property "softsign(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling softsign(MLOperand) on builder with too few arguments must throw TypeError
+[PASS] MLGraphBuilder interface: builder must inherit property "softsign()" with the proper type
 [PASS] MLGraphBuilder interface: builder must inherit property "split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions)" with the proper type
 [PASS] MLGraphBuilder interface: calling split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions) on builder with too few arguments must throw TypeError
 [FAIL] MLGraphBuilder interface: builder must inherit property "squeeze(MLOperand, optional MLSqueezeOptions)" with the proper type
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/idlharness.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/webnn/idlharness.https.any.worker-expected.txt
index 2f2104b..88ce4f2a 100644
--- a/third_party/blink/web_tests/platform/win/external/wpt/webnn/idlharness.https.any.worker-expected.txt
+++ b/third_party/blink/web_tests/platform/win/external/wpt/webnn/idlharness.https.any.worker-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 414 tests; 325 PASS, 89 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 414 tests; 345 PASS, 69 FAIL, 0 TIMEOUT, 0 NOTRUN.
 [FAIL] idl_test setup
   promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'buildSync' on 'MLGraphBuilder': The input layout nchw is not supported."
 [PASS] idl_test validation
@@ -229,18 +229,13 @@
 [PASS] MLGraphBuilder interface: operation pow(MLOperand, MLOperand)
 [PASS] MLGraphBuilder interface: operation abs(MLOperand)
 [PASS] MLGraphBuilder interface: operation ceil(MLOperand)
-[FAIL] MLGraphBuilder interface: operation cos(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "cos" missing
-[FAIL] MLGraphBuilder interface: operation exp(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "exp" missing
+[PASS] MLGraphBuilder interface: operation cos(MLOperand)
+[PASS] MLGraphBuilder interface: operation exp(MLOperand)
 [PASS] MLGraphBuilder interface: operation floor(MLOperand)
-[FAIL] MLGraphBuilder interface: operation log(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "log" missing
+[PASS] MLGraphBuilder interface: operation log(MLOperand)
 [PASS] MLGraphBuilder interface: operation neg(MLOperand)
-[FAIL] MLGraphBuilder interface: operation sin(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "sin" missing
-[FAIL] MLGraphBuilder interface: operation tan(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "tan" missing
+[PASS] MLGraphBuilder interface: operation sin(MLOperand)
+[PASS] MLGraphBuilder interface: operation tan(MLOperand)
 [PASS] MLGraphBuilder interface: operation elu(MLOperand, optional MLEluOptions)
 [PASS] MLGraphBuilder interface: operation elu(optional MLEluOptions)
 [PASS] MLGraphBuilder interface: operation gemm(MLOperand, MLOperand, optional MLGemmOptions)
@@ -298,10 +293,8 @@
   assert_own_property: interface prototype object missing non-static operation expected property "softplus" missing
 [FAIL] MLGraphBuilder interface: operation softplus(optional MLSoftplusOptions)
   assert_own_property: interface prototype object missing non-static operation expected property "softplus" missing
-[FAIL] MLGraphBuilder interface: operation softsign(MLOperand)
-  assert_own_property: interface prototype object missing non-static operation expected property "softsign" missing
-[FAIL] MLGraphBuilder interface: operation softsign()
-  assert_own_property: interface prototype object missing non-static operation expected property "softsign" missing
+[PASS] MLGraphBuilder interface: operation softsign(MLOperand)
+[PASS] MLGraphBuilder interface: operation softsign()
 [PASS] MLGraphBuilder interface: operation split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions)
 [FAIL] MLGraphBuilder interface: operation squeeze(MLOperand, optional MLSqueezeOptions)
   assert_own_property: interface prototype object missing non-static operation expected property "squeeze" missing
@@ -354,30 +347,20 @@
 [PASS] MLGraphBuilder interface: calling abs(MLOperand) on builder with too few arguments must throw TypeError
 [PASS] MLGraphBuilder interface: builder must inherit property "ceil(MLOperand)" with the proper type
 [PASS] MLGraphBuilder interface: calling ceil(MLOperand) on builder with too few arguments must throw TypeError
-[FAIL] MLGraphBuilder interface: builder must inherit property "cos(MLOperand)" with the proper type
-  assert_inherits: property "cos" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling cos(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "cos" not found in prototype chain
-[FAIL] MLGraphBuilder interface: builder must inherit property "exp(MLOperand)" with the proper type
-  assert_inherits: property "exp" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling exp(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "exp" not found in prototype chain
+[PASS] MLGraphBuilder interface: builder must inherit property "cos(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling cos(MLOperand) on builder with too few arguments must throw TypeError
+[PASS] MLGraphBuilder interface: builder must inherit property "exp(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling exp(MLOperand) on builder with too few arguments must throw TypeError
 [PASS] MLGraphBuilder interface: builder must inherit property "floor(MLOperand)" with the proper type
 [PASS] MLGraphBuilder interface: calling floor(MLOperand) on builder with too few arguments must throw TypeError
-[FAIL] MLGraphBuilder interface: builder must inherit property "log(MLOperand)" with the proper type
-  assert_inherits: property "log" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling log(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "log" not found in prototype chain
+[PASS] MLGraphBuilder interface: builder must inherit property "log(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling log(MLOperand) on builder with too few arguments must throw TypeError
 [PASS] MLGraphBuilder interface: builder must inherit property "neg(MLOperand)" with the proper type
 [PASS] MLGraphBuilder interface: calling neg(MLOperand) on builder with too few arguments must throw TypeError
-[FAIL] MLGraphBuilder interface: builder must inherit property "sin(MLOperand)" with the proper type
-  assert_inherits: property "sin" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling sin(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "sin" not found in prototype chain
-[FAIL] MLGraphBuilder interface: builder must inherit property "tan(MLOperand)" with the proper type
-  assert_inherits: property "tan" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling tan(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "tan" not found in prototype chain
+[PASS] MLGraphBuilder interface: builder must inherit property "sin(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling sin(MLOperand) on builder with too few arguments must throw TypeError
+[PASS] MLGraphBuilder interface: builder must inherit property "tan(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling tan(MLOperand) on builder with too few arguments must throw TypeError
 [PASS] MLGraphBuilder interface: builder must inherit property "elu(MLOperand, optional MLEluOptions)" with the proper type
 [PASS] MLGraphBuilder interface: calling elu(MLOperand, optional MLEluOptions) on builder with too few arguments must throw TypeError
 [PASS] MLGraphBuilder interface: builder must inherit property "elu(optional MLEluOptions)" with the proper type
@@ -484,12 +467,9 @@
   assert_inherits: property "softplus" not found in prototype chain
 [FAIL] MLGraphBuilder interface: calling softplus(optional MLSoftplusOptions) on builder with too few arguments must throw TypeError
   assert_inherits: property "softplus" not found in prototype chain
-[FAIL] MLGraphBuilder interface: builder must inherit property "softsign(MLOperand)" with the proper type
-  assert_inherits: property "softsign" not found in prototype chain
-[FAIL] MLGraphBuilder interface: calling softsign(MLOperand) on builder with too few arguments must throw TypeError
-  assert_inherits: property "softsign" not found in prototype chain
-[FAIL] MLGraphBuilder interface: builder must inherit property "softsign()" with the proper type
-  assert_inherits: property "softsign" not found in prototype chain
+[PASS] MLGraphBuilder interface: builder must inherit property "softsign(MLOperand)" with the proper type
+[PASS] MLGraphBuilder interface: calling softsign(MLOperand) on builder with too few arguments must throw TypeError
+[PASS] MLGraphBuilder interface: builder must inherit property "softsign()" with the proper type
 [PASS] MLGraphBuilder interface: builder must inherit property "split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions)" with the proper type
 [PASS] MLGraphBuilder interface: calling split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions) on builder with too few arguments must throw TypeError
 [FAIL] MLGraphBuilder interface: builder must inherit property "squeeze(MLOperand, optional MLSqueezeOptions)" with the proper type
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/softsign.https.any-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/webnn/softsign.https.any-expected.txt
new file mode 100644
index 0000000..881f47f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/external/wpt/webnn/softsign.https.any-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+[FAIL] softsign positive float32 1D tensor / async
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (softsign) is not supported."
+[FAIL] softsign negative float32 1D tensor / async
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (softsign) is not supported."
+[FAIL] softsign float32 2D tensor / async
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (softsign) is not supported."
+[FAIL] softsign float32 3D tensor / async
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (softsign) is not supported."
+[FAIL] softsign float32 4D tensor / async
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (softsign) is not supported."
+[FAIL] softsign float32 5D tensor / async
+  promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (softsign) is not supported."
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/softsign.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/webnn/softsign.https.any.worker-expected.txt
new file mode 100644
index 0000000..97bc72a6
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/external/wpt/webnn/softsign.https.any.worker-expected.txt
@@ -0,0 +1,27 @@
+This is a testharness.js-based test.
+[FAIL] softsign positive float32 1D tensor / sync
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (softsign) is not supported.
+[FAIL] softsign negative float32 1D tensor / sync
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (softsign) is not supported.
+[FAIL] softsign float32 2D tensor / sync
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (softsign) is not supported.
+[FAIL] softsign float32 3D tensor / sync
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (softsign) is not supported.
+[FAIL] softsign float32 4D tensor / sync
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (softsign) is not supported.
+[FAIL] softsign float32 5D tensor / sync
+  Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (softsign) is not supported.
+[FAIL] softsign positive float32 1D tensor / async
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
+[FAIL] softsign negative float32 1D tensor / async
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
+[FAIL] softsign float32 2D tensor / async
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
+[FAIL] softsign float32 3D tensor / async
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
+[FAIL] softsign float32 4D tensor / async
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
+[FAIL] softsign float32 5D tensor / async
+  promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
index 8e19d85..364d9b6 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -1185,13 +1185,16 @@
 [Worker]     method constructor
 [Worker]     method conv2d
 [Worker]     method convTranspose2d
+[Worker]     method cos
 [Worker]     method div
 [Worker]     method elu
+[Worker]     method exp
 [Worker]     method floor
 [Worker]     method gemm
 [Worker]     method hardSwish
 [Worker]     method input
 [Worker]     method leakyRelu
+[Worker]     method log
 [Worker]     method matmul
 [Worker]     method max
 [Worker]     method maxPool2d
@@ -1215,10 +1218,13 @@
 [Worker]     method resample2d
 [Worker]     method reshape
 [Worker]     method sigmoid
+[Worker]     method sin
 [Worker]     method slice
 [Worker]     method softmax
+[Worker]     method softsign
 [Worker]     method split
 [Worker]     method sub
+[Worker]     method tan
 [Worker]     method tanh
 [Worker]     method transpose
 [Worker] interface MLOperand
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
index aace6872..4518a927 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -5622,13 +5622,16 @@
     method constructor
     method conv2d
     method convTranspose2d
+    method cos
     method div
     method elu
+    method exp
     method floor
     method gemm
     method hardSwish
     method input
     method leakyRelu
+    method log
     method matmul
     method max
     method maxPool2d
@@ -5652,10 +5655,13 @@
     method resample2d
     method reshape
     method sigmoid
+    method sin
     method slice
     method softmax
+    method softsign
     method split
     method sub
+    method tan
     method tanh
     method transpose
 interface MLModelLoader
diff --git a/third_party/catapult b/third_party/catapult
index c6db8519..124950e 160000
--- a/third_party/catapult
+++ b/third_party/catapult
@@ -1 +1 @@
-Subproject commit c6db8519c02ae6a5afac0358c266dc3e5f2fd803
+Subproject commit 124950ee2c619428b16fabb3a5389fcbcfd7d665
diff --git a/third_party/chromium-variations b/third_party/chromium-variations
index 37afeb4..080ed7f 160000
--- a/third_party/chromium-variations
+++ b/third_party/chromium-variations
@@ -1 +1 @@
-Subproject commit 37afeb4fa9594d2497b5b8e13a94509c54201680
+Subproject commit 080ed7fb83d2605473c71f2661185fe3364d8a34
diff --git a/third_party/cros-components/src b/third_party/cros-components/src
index d409ac3..c3435a5 160000
--- a/third_party/cros-components/src
+++ b/third_party/cros-components/src
@@ -1 +1 @@
-Subproject commit d409ac304472ac7b2ea569d9e3ac47d238de1182
+Subproject commit c3435a5e6829b9a4746456e5a1beb2ef23926be4
diff --git a/third_party/dawn b/third_party/dawn
index e2cd8aa..6f2cbf6 160000
--- a/third_party/dawn
+++ b/third_party/dawn
@@ -1 +1 @@
-Subproject commit e2cd8aade99ffd2d2b97fe87fd43b08f22002692
+Subproject commit 6f2cbf61890b1a644269326bc50dd82bcaf58f7e
diff --git a/third_party/depot_tools b/third_party/depot_tools
index 0c5e865..ccc34d2 160000
--- a/third_party/depot_tools
+++ b/third_party/depot_tools
@@ -1 +1 @@
-Subproject commit 0c5e8652fe1fefee1c291cbf05ca3a41b9f66890
+Subproject commit ccc34d2b44d8520f9b4c2697001f36444c78cd66
diff --git a/third_party/devtools-frontend-internal b/third_party/devtools-frontend-internal
index 2c4d976..54c8de9 160000
--- a/third_party/devtools-frontend-internal
+++ b/third_party/devtools-frontend-internal
@@ -1 +1 @@
-Subproject commit 2c4d976019118bab0f3e12634570728fcb658494
+Subproject commit 54c8de91358fc2d5d39b20ba4a159bbe4dae2c22
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src
index 1088b03..fb3ba5a 160000
--- a/third_party/devtools-frontend/src
+++ b/third_party/devtools-frontend/src
@@ -1 +1 @@
-Subproject commit 1088b0366ce6feff0dab1f8ef102a6d2ee801ed3
+Subproject commit fb3ba5ad261f335023e2c2160b8a9b59f5770075
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium
index fff697b..ed6d18ba 100644
--- a/third_party/freetype/README.chromium
+++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@
 Name: FreeType
 URL: http://www.freetype.org/
-Version: VER-2-13-2-58-ge92027377
-Revision: e9202737747ac008819d24a39c54584200c7a254
+Version: VER-2-13-2-59-g6338f2a68
+Revision: 6338f2a6814b3f50a0bb3a4c563ef30e4561041a
 CPEPrefix: cpe:/a:freetype:freetype:2.13.2
 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent
          JPEG Group) licenses"
diff --git a/third_party/freetype/src b/third_party/freetype/src
index e920273..6338f2a 160000
--- a/third_party/freetype/src
+++ b/third_party/freetype/src
@@ -1 +1 @@
-Subproject commit e9202737747ac008819d24a39c54584200c7a254
+Subproject commit 6338f2a6814b3f50a0bb3a4c563ef30e4561041a
diff --git a/third_party/instrumented_libraries/.style.yapf b/third_party/instrumented_libraries/.style.yapf
new file mode 100644
index 0000000..557fa7b
--- /dev/null
+++ b/third_party/instrumented_libraries/.style.yapf
@@ -0,0 +1,2 @@
+[style]
+based_on_style = pep8
diff --git a/third_party/instrumented_libraries/focal/BUILD.gn b/third_party/instrumented_libraries/focal/BUILD.gn
index 604c2bb9..4c0004d 100644
--- a/third_party/instrumented_libraries/focal/BUILD.gn
+++ b/third_party/instrumented_libraries/focal/BUILD.gn
@@ -170,8 +170,8 @@
       args += [ "--git-revision=${invoker.git_revision}" ]
     }
 
-    if (defined(invoker.no_configure) && invoker.no_configure) {
-      args += [ "--no-configure" ]
+    if (defined(invoker.make_targets)) {
+      args += [ "--make-targets=${invoker.make_targets}" ]
     }
   }
 }
@@ -219,8 +219,7 @@
 instrumented_library("guest-oslogin") {
   git_url = "https://github.com/GoogleCloudPlatform/guest-oslogin.git"
   git_revision = "f59b7f38c21b4794282ddf12fd4a6083cd99e1e4"
-  # guest-oslogin is built only with `make`.
-  no_configure = true
+
   # Work around an issue where header files are passed to the linker.
   patches = [ "patches/guest-oslogin.diff" ]
 }
@@ -451,7 +450,7 @@
     # Do not use loadable modules. Same as with Pango, there's no easy way
     # to make gdk-pixbuf pick instrumented versions over system-installed
     # ones.
-    "-Dbuiltin_loaders='all'",
+    "-Dbuiltin_loaders=all",
   ]
   pre_build = "scripts/pre-build/libgdk-pixbuf2.0-0.sh"
 
@@ -856,5 +855,5 @@
 }
 
 instrumented_library("zlib1g") {
-  build_method = "custom_zlib"
+  make_targets = [ "libz.so.1.2.11" ]
 }
diff --git a/third_party/instrumented_libraries/focal/scripts/download_build_install.py b/third_party/instrumented_libraries/focal/scripts/download_build_install.py
index db043fe..e1d8fdc4 100755
--- a/third_party/instrumented_libraries/focal/scripts/download_build_install.py
+++ b/third_party/instrumented_libraries/focal/scripts/download_build_install.py
@@ -2,7 +2,6 @@
 # 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.
-
 """Downloads, builds (with instrumentation) and installs shared libraries."""
 
 import argparse
@@ -20,603 +19,642 @@
 
 SCRIPT_ABSOLUTE_PATH = os.path.dirname(os.path.abspath(__file__))
 
+
 def unescape_flags(s):
-  """Un-escapes build flags received from GYP.
+    """Un-escapes build flags received from GN.
 
-  GYP escapes build flags as if they are to be inserted directly into a command
-  line, wrapping each flag in double quotes. When flags are passed via
-  CFLAGS/LDFLAGS instead, double quotes must be dropped.
-  """
-  if not s:
-    return ''
-  try:
-    return ' '.join(ast.literal_eval(s))
-  except (SyntaxError, ValueError):
-    return ' '.join(shlex.split(s))
+    GN escapes build flags as if they are to be inserted directly into a command
+    line, wrapping each flag in double quotes. When flags are passed via
+    CFLAGS/LDFLAGS instead, double quotes must be dropped.
+    """
+    if not s:
+        return []
+    try:
+        return ast.literal_eval(s)
+    except (SyntaxError, ValueError):
+        return shlex.split(s)
 
 
-def real_path(path_relative_to_gyp):
-  """Returns the absolute path to a file.
+def real_path(path_relative_to_gn):
+    """Returns the absolute path to a file.
 
-  GYP generates paths relative to the location of the .gyp file, which is one
-  level above the location of this script. This function converts them to
-  absolute paths.
-  """
-  return os.path.realpath(os.path.join(SCRIPT_ABSOLUTE_PATH, '..',
-                                       path_relative_to_gyp))
+    GN generates paths relative to the build directory, which is one
+    level above the location of this script. This function converts them to
+    absolute paths.
+    """
+    return os.path.realpath(
+        os.path.join(SCRIPT_ABSOLUTE_PATH, "..", path_relative_to_gn))
 
 
 class InstrumentedPackageBuilder(object):
-  """Checks out and builds a single instrumented package."""
-  def __init__(self, args, clobber):
-    self._cc = args.cc
-    self._cxx = args.cxx
-    self._extra_configure_flags = unescape_flags(args.extra_configure_flags)
-    self._libdir = args.libdir
-    self._package = args.package
-    self._patches = [real_path(patch) for patch in args.patch]
-    self._pre_build = \
-        real_path(args.pre_build) if args.pre_build else None
-    self._verbose = args.verbose
-    self._clobber = clobber
-    self._working_dir = os.path.join(
-        real_path(args.intermediate_dir), self._package, '')
+    """Checks out and builds a single instrumented package."""
+    def __init__(self, args, clobber):
+        self._cc = args.cc
+        self._cxx = args.cxx
+        self._extra_configure_flags = unescape_flags(
+            args.extra_configure_flags)
+        self._libdir = args.libdir
+        self._package = args.package
+        self._patches = [real_path(patch) for patch in args.patch]
+        self._pre_build = real_path(args.pre_build) if args.pre_build else None
+        self._verbose = args.verbose
+        self._clobber = clobber
+        self._working_dir = os.path.join(real_path(args.intermediate_dir),
+                                         self._package, "")
 
-    product_dir = real_path(args.product_dir)
-    self._destdir = os.path.join(
-        product_dir, 'instrumented_libraries')
-    self._source_archives_dir = os.path.join(
-        product_dir, 'instrumented_libraries', 'sources', self._package)
+        product_dir = real_path(args.product_dir)
+        self._destdir = os.path.join(product_dir, "instrumented_libraries")
+        self._source_archives_dir = os.path.join(product_dir,
+                                                 "instrumented_libraries",
+                                                 "sources", self._package)
 
-    self._cflags = unescape_flags(args.cflags)
-    if args.sanitizer_ignorelist:
-      ignorelist_file = real_path(args.sanitizer_ignorelist)
-      self._cflags += ' -fsanitize-blacklist=%s' % ignorelist_file  # nocheck
+        self._cflags = unescape_flags(args.cflags)
+        if args.sanitizer_ignorelist:
+            ignorelist_file = real_path(args.sanitizer_ignorelist)
+            self._cflags += ["-fsanitize-blacklist=%s" % ignorelist_file]
 
-    self._ldflags = unescape_flags(args.ldflags)
+        self._ldflags = unescape_flags(args.ldflags)
 
-    self.init_build_env(eval(args.env))
+        self.init_build_env(eval(args.env))
 
-    self._git_url = args.git_url
-    self._git_revision = args.git_revision
+        self._git_url = args.git_url
+        self._git_revision = args.git_revision
 
-    self._no_configure = args.no_configure
+        self._make_targets = unescape_flags(args.make_targets)
 
-    # Initialized later.
-    self._source_dir = None
-    self._source_archives = None
+        # Initialized later.
+        self._source_dir = ""
+        self._source_archives = ""
 
-  def init_build_env(self, args_env):
-    self._build_env = os.environ.copy()
+    def init_build_env(self, args_env):
+        self._build_env = os.environ.copy()
 
-    self._build_env.update(dict(args_env))
+        self._build_env.update(dict(args_env))
 
-    self._build_env['CC'] = self._cc
-    self._build_env['CXX'] = self._cxx
+        self._build_env["CC"] = self._cc
+        self._build_env["CXX"] = self._cxx
 
-    self._build_env['CFLAGS'] = self._cflags
-    self._build_env['CXXFLAGS'] = self._cflags
-    self._build_env['LDFLAGS'] = self._ldflags
+        self._build_env["CFLAGS"] = " ".join(self._cflags)
+        self._build_env["CXXFLAGS"] = " ".join(self._cflags)
+        self._build_env["LDFLAGS"] = " ".join(self._ldflags)
 
-    # libappindicator1 needs this.
-    self._build_env['CSC'] = '/usr/bin/mono-csc'
+        # libappindicator1 needs this.
+        self._build_env["CSC"] = "/usr/bin/mono-csc"
 
-  def shell_call(self, command, env=None, cwd=None, ignore_ret_code=False):
-    """Wrapper around subprocess.Popen().
+    def shell_call(self,
+                   command,
+                   env=None,
+                   cwd=None,
+                   ignore_ret_code=False,
+                   shell=False):
+        """Wrapper around subprocess.Popen().
 
-    Calls command with specific environment and verbosity using
-    subprocess.Popen().
-    """
-    child = subprocess.Popen(
-        command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
-        env=env, shell=True, cwd=cwd)
-    stdout = child.communicate()[0].decode('utf-8')
-    if ignore_ret_code:
-      if self._verbose:
-        print(stdout)
-      return stdout
-    if self._verbose or child.returncode:
-      print(stdout)
-    if child.returncode:
-      raise Exception('Failed to run: %s' % command)
-    return stdout
+        Calls command with specific environment and verbosity using
+        subprocess.Popen().
+        """
+        child = subprocess.Popen(
+            command,
+            stdout=subprocess.PIPE,
+            stderr=subprocess.STDOUT,
+            env=env,
+            shell=shell,
+            cwd=cwd,
+        )
+        stdout = child.communicate()[0].decode("utf-8")
+        if ignore_ret_code:
+            if self._verbose:
+                print(stdout)
+            return stdout
+        if self._verbose or child.returncode:
+            print(stdout)
+        if child.returncode:
+            raise Exception("Failed to run: %s" % command)
+        return stdout
 
-  def maybe_download_source(self):
-    """Checks out the source code (if needed).
+    def maybe_download_source(self):
+        """Checks out the source code (if needed).
 
-    Checks out the source code for the package, if required (i.e. unless running
-    in no-clobber mode). Initializes self._source_dir and self._source_archives.
-    """
-    get_fresh_source = self._clobber or not os.path.exists(self._working_dir)
-    if get_fresh_source:
-      shutil.rmtree(self._working_dir, ignore_errors=True)
-      os.makedirs(self._working_dir)
+        Checks out the source code for the package, if required (i.e. unless running
+        in no-clobber mode). Initializes self._source_dir and self._source_archives.
+        """
+        command = ""
+        get_fresh_source = self._clobber or not os.path.exists(
+            self._working_dir)
+        if get_fresh_source:
+            shutil.rmtree(self._working_dir, ignore_errors=True)
+            os.makedirs(self._working_dir)
 
-      if self._git_url:
-        command = 'git clone %s' % self._git_url
-        self.shell_call(command, cwd=self._working_dir)
-      else:
-        # Download one source package at a time, otherwise, there will
-        # be connection errors in gnutls_handshake().
-        lock = open('apt-source-lock', 'w')
-        fcntl.flock(lock, fcntl.LOCK_EX)
-        command = 'apt-get source %s' % self._package
-        self.shell_call(command, cwd=self._working_dir)
-        fcntl.flock(lock, fcntl.LOCK_UN)
+            if self._git_url:
+                command = ["git", "clone", self._git_url]
+                self.shell_call(command, cwd=self._working_dir)
+            else:
+                # Download one source package at a time, otherwise, there will
+                # be connection errors in gnutls_handshake().
+                lock = open("apt-source-lock", "w")
+                fcntl.flock(lock, fcntl.LOCK_EX)
+                command = ["apt-get", "source", self._package]
+                self.shell_call(command, cwd=self._working_dir)
+                fcntl.flock(lock, fcntl.LOCK_UN)
 
-    (dirpath, dirnames, filenames) = next(os.walk(self._working_dir))
+        (dirpath, dirnames, filenames) = next(os.walk(self._working_dir))
 
-    if len(dirnames) != 1:
-      raise Exception( '`%s\' must create exactly one subdirectory.' % command)
-    self._source_component = dirnames[0]
-    self._source_dir = os.path.join(dirpath, self._source_component, '')
-    if self._git_url:
-      self.shell_call('git checkout %s' % self._git_revision,
-                      cwd=self._source_dir)
-    else:
-      if len(filenames) == 0:
-        raise Exception('Can\'t find source files after `%s\'.' % command)
-      self._source_archives = \
-          [os.path.join(dirpath, filename) for filename in filenames]
+        if len(dirnames) != 1:
+            raise Exception("`%s' must create exactly one subdirectory." %
+                            command)
+        self._source_component = dirnames[0]
+        self._source_dir = os.path.join(dirpath, self._source_component, "")
+        if self._git_url:
+            self.shell_call(["git", "checkout", self._git_revision],
+                            cwd=self._source_dir)
+        else:
+            if len(filenames) == 0:
+                raise Exception("Can't find source files after `%s'." %
+                                command)
+            self._source_archives = [
+                os.path.join(dirpath, filename) for filename in filenames
+            ]
 
-    return get_fresh_source
+        return get_fresh_source
 
-  def patch_source(self):
-    for patch in self._patches:
-      self.shell_call('patch -p1 -i %s' % patch, cwd=self._source_dir)
-    if self._pre_build:
-      self.shell_call(self._pre_build, cwd=self._source_dir)
+    def patch_source(self):
+        for patch in self._patches:
+            self.shell_call(["patch", "-p1", "-i", patch],
+                            cwd=self._source_dir)
+        if self._pre_build:
+            self.shell_call([self._pre_build], cwd=self._source_dir)
 
-  def copy_source_archives(self):
-    """Copies the downloaded source archives to the output dir.
+    def copy_source_archives(self):
+        """Copies the downloaded source archives to the output dir.
 
-    For license compliance purposes, every Chromium build that includes
-    instrumented libraries must include their full source code.
-    """
-    shutil.rmtree(self._source_archives_dir, ignore_errors=True)
-    os.makedirs(self._source_archives_dir)
-    if self._git_url:
-      dest = os.path.join(self._source_archives_dir, self._source_component)
-      shutil.copytree(self._source_dir, dest)
-    else:
-      for filename in self._source_archives:
-        shutil.copy(filename, self._source_archives_dir)
-    for patch in self._patches:
-      shutil.copy(patch, self._source_archives_dir)
+        For license compliance purposes, every Chromium build that includes
+        instrumented libraries must include their full source code.
+        """
+        shutil.rmtree(self._source_archives_dir, ignore_errors=True)
+        os.makedirs(self._source_archives_dir)
+        if self._git_url:
+            dest = os.path.join(self._source_archives_dir,
+                                self._source_component)
+            shutil.copytree(self._source_dir, dest)
+        else:
+            for filename in self._source_archives:
+                shutil.copy(filename, self._source_archives_dir)
+        for patch in self._patches:
+            shutil.copy(patch, self._source_archives_dir)
 
-  def download_build_install(self):
-    got_fresh_source = self.maybe_download_source()
-    if got_fresh_source:
-      self.patch_source()
-      self.copy_source_archives()
+    def download_build_install(self):
+        got_fresh_source = self.maybe_download_source()
+        if got_fresh_source:
+            self.patch_source()
+            self.copy_source_archives()
 
-    if not os.path.exists(self.dest_libdir()):
-      os.makedirs(self.dest_libdir())
+        if not os.path.exists(self.dest_libdir()):
+            os.makedirs(self.dest_libdir())
 
-    try:
-      self.build_and_install()
-    except Exception as exception:
-      print('ERROR: Failed to build package %s. Have you '
-            'run src/third_party/instrumented_libraries/scripts/'
-            'install-build-deps.sh?' % self._package)
-      raise
+        try:
+            self.build_and_install()
+        except Exception as exception:
+            print("ERROR: Failed to build package %s. Have you "
+                  "run src/third_party/instrumented_libraries/scripts/"
+                  "install-build-deps.sh?" % self._package)
+            raise
 
-    # Touch a text file to indicate package is installed.
-    stamp_file = os.path.join(self._destdir, '%s.txt' % self._package)
-    open(stamp_file, 'w').close()
+        # Touch a text file to indicate package is installed.
+        stamp_file = os.path.join(self._destdir, "%s.txt" % self._package)
+        open(stamp_file, "w").close()
 
-    # Remove downloaded package and generated temporary build files. Failed
-    # builds intentionally skip this step to help debug build failures.
-    if self._clobber:
-      self.shell_call('rm -rf %s' % self._working_dir)
+        # Remove downloaded package and generated temporary build files. Failed
+        # builds intentionally skip this step to help debug build failures.
+        if self._clobber:
+            self.shell_call(["rm", "-rf", self._working_dir])
 
-  def fix_rpaths(self, directory):
-    # TODO(eugenis): reimplement fix_rpaths.sh in Python.
-    script = real_path('scripts/fix_rpaths.sh')
-    self.shell_call("%s %s" % (script, directory))
+    def fix_rpaths(self, directory):
+        # TODO(eugenis): reimplement fix_rpaths.sh in Python.
+        script = real_path("scripts/fix_rpaths.sh")
+        self.shell_call([script, directory])
 
-  def temp_dir(self):
-    """Returns the directory which will be passed to `make install'."""
-    return os.path.join(self._source_dir, 'debian', 'instrumented_build')
+    def temp_dir(self):
+        """Returns the directory which will be passed to `make install'."""
+        return os.path.join(self._source_dir, "debian", "instrumented_build")
 
-  def temp_libdir(self):
-    """Returns the directory under temp_dir() containing the DSOs."""
-    return os.path.join(self.temp_dir(), self._libdir)
+    def temp_libdir(self):
+        """Returns the directory under temp_dir() containing the DSOs."""
+        return os.path.join(self.temp_dir(), self._libdir)
 
-  def dest_libdir(self):
-    """Returns the final location of the DSOs."""
-    return os.path.join(self._destdir, self._libdir)
+    def dest_libdir(self):
+        """Returns the final location of the DSOs."""
+        return os.path.join(self._destdir, self._libdir)
 
-  def cleanup_after_install(self):
-    """Removes unneeded files in self.temp_libdir()."""
-    # .la files are not needed, nuke them.
-    # In case --no-static is not supported, nuke any static libraries we built.
-    self.shell_call(
-        'find %s -name *.la -or -name *.a | xargs rm -f' % self.temp_libdir())
-    # .pc files are not needed.
-    self.shell_call('rm %s/pkgconfig -rf' % self.temp_libdir())
+    def cleanup_after_install(self):
+        """Removes unneeded files in self.temp_libdir()."""
+        # .la files are not needed, nuke them.
+        # In case --no-static is not supported, nuke any static libraries we built.
+        self.shell_call(
+            "find %s -name *.la -or -name *.a | xargs rm -f" %
+            self.temp_libdir(),
+            shell=True,
+        )
+        # .pc files are not needed.
+        self.shell_call(["rm", "-rf", "%s/pkgconfig" % self.temp_libdir()])
 
-  def make(self, args, env=None, cwd=None, ignore_ret_code=False):
-    """Invokes `make'.
+    def make(self, args, env=None, cwd=None, ignore_ret_code=False):
+        """Invokes `make'.
 
-    Invokes `make' with the specified args, using self._build_env and
-    self._source_dir by default.
-    """
-    if cwd is None:
-      cwd = self._source_dir
-    if env is None:
-      env = self._build_env
-    cmd = ['make'] + args
-    self.shell_call(' '.join(cmd), env=env, cwd=cwd,
-                    ignore_ret_code=ignore_ret_code)
+        Invokes `make' with the specified args, using self._build_env and
+        self._source_dir by default.
+        """
+        if cwd is None:
+            cwd = self._source_dir
+        if env is None:
+            env = self._build_env
+        self.shell_call(["make"] + args,
+                        env=env,
+                        cwd=cwd,
+                        ignore_ret_code=ignore_ret_code)
 
-  def make_install(self, args, **kwargs):
-    """Invokes `make install'."""
-    self.make(['install'] + args, **kwargs)
+    def make_install(self, args, **kwargs):
+        """Invokes `make install'."""
+        self.make(["install"] + args, **kwargs)
 
-  def build_and_install(self, targets=[]):
-    """Builds and installs the DSOs.
+    def build_and_install(self):
+        """Builds and installs the DSOs.
 
-    Builds the package with ./configure + make, installs it to a temporary
-    location, then moves the relevant files to their permanent location.
-    """
-    if not self._no_configure:
-      configure_cmd = './configure --libdir=/%s/ %s' % (
-          self._libdir, self._extra_configure_flags)
-      self.shell_call(configure_cmd, env=self._build_env, cwd=self._source_dir)
+        Builds the package with ./configure + make, installs it to a temporary
+        location, then moves the relevant files to their permanent location.
+        """
+        if os.path.exists(os.path.join(self._source_dir, "configure")):
+            configure_cmd = [
+                "./configure",
+                "--libdir=/%s/" % self._libdir,
+            ] + self._extra_configure_flags
+            self.shell_call(configure_cmd,
+                            env=self._build_env,
+                            cwd=self._source_dir)
 
-    # Some makefiles use BUILDROOT or INSTALL_ROOT instead of DESTDIR.
-    args = ['DESTDIR', 'BUILDROOT', 'INSTALL_ROOT']
-    make_args = ['%s=%s' % (name, self.temp_dir()) for name in args]
-    self.make(make_args + targets)
+        # Some makefiles use BUILDROOT or INSTALL_ROOT instead of DESTDIR.
+        args = ["DESTDIR", "BUILDROOT", "INSTALL_ROOT"]
+        make_args = ["%s=%s" % (name, self.temp_dir()) for name in args]
+        self.make(make_args + self._make_targets)
 
-    self.make_install(make_args)
+        self.make_install(make_args)
 
-    self.post_install()
+        self.post_install()
 
-  def post_install(self):
-    self.cleanup_after_install()
+    def post_install(self):
+        self.cleanup_after_install()
 
-    self.fix_rpaths(self.temp_libdir())
+        self.fix_rpaths(self.temp_libdir())
 
-    # Now move the contents of the temporary destdir to their final place.
-    # We only care for the contents of LIBDIR.
-    self.shell_call('cp %s/* %s/ -rdf' % (self.temp_libdir(),
-                                          self.dest_libdir()))
+        # Now move the contents of the temporary destdir to their final place.
+        # We only care for the contents of LIBDIR.
+        self.shell_call("cp %s/* %s/ -rdf" %
+                        (self.temp_libdir(), self.dest_libdir()),
+                        shell=True)
 
 
 class DebianBuilder(InstrumentedPackageBuilder):
-  """Builds a package using Debian's build system.
+    """Builds a package using Debian's build system.
 
-  TODO(spang): Probably the rest of the packages should also use this method..
-  """
+    TODO(spang): Probably the rest of the packages should also use this method..
+    """
+    def init_build_env(self, args_env):
+        self._build_env = os.environ.copy()
 
-  def init_build_env(self, args_env):
-    self._build_env = os.environ.copy()
+        self._build_env.update(dict(args_env))
 
-    self._build_env.update(dict(args_env))
+        self._build_env["CC"] = self._cc
+        self._build_env["CXX"] = self._cxx
 
-    self._build_env['CC'] = self._cc
-    self._build_env['CXX'] = self._cxx
+        self._build_env["DEB_CFLAGS_APPEND"] = " ".join(self._cflags)
+        self._build_env["DEB_CXXFLAGS_APPEND"] = " ".join(self._cflags)
+        self._build_env["DEB_LDFLAGS_APPEND"] = " ".join(self._ldflags)
+        self._build_env["DEB_BUILD_OPTIONS"] = (
+            "nocheck notest nodoc nostrip parallel=%d" % os.cpu_count())
 
-    self._build_env['DEB_CFLAGS_APPEND'] = self._cflags
-    self._build_env['DEB_CXXFLAGS_APPEND'] = self._cflags
-    self._build_env['DEB_LDFLAGS_APPEND'] = self._ldflags
-    self._build_env['DEB_BUILD_OPTIONS'] = \
-      'nocheck notest nodoc nostrip parallel=%d' % os.cpu_count()
+    def build_and_install(self):
+        self.build_debian_packages()
+        self.install_packaged_libs()
 
-  def build_and_install(self):
-    self.build_debian_packages()
-    self.install_packaged_libs()
+    def build_debian_packages(self):
+        configure_cmd = ["dpkg-buildpackage", "-B", "-uc"]
+        self.shell_call(configure_cmd,
+                        env=self._build_env,
+                        cwd=self._source_dir)
 
-  def build_debian_packages(self):
-    configure_cmd = 'dpkg-buildpackage -B -uc'
-    self.shell_call(configure_cmd, env=self._build_env, cwd=self._source_dir)
+    def install_packaged_libs(self):
+        for deb_file in self.get_deb_files():
+            self.shell_call(["dpkg-deb", "-x", deb_file, self.temp_dir()])
 
-  def install_packaged_libs(self):
-    for deb_file in self.get_deb_files():
-      self.shell_call("dpkg-deb -x %s %s" % (deb_file, self.temp_dir()))
+        dpkg_arch_cmd = ["dpkg-architecture", "-qDEB_HOST_MULTIARCH"]
+        dpkg_arch = self.shell_call(dpkg_arch_cmd).strip()
+        lib_dirs = [
+            "usr/lib/%s" % dpkg_arch,
+            "lib/%s" % dpkg_arch,
+        ]
+        lib_paths = [
+            path for lib_dir in lib_dirs for path in glob.glob(
+                os.path.join(self.temp_dir(), lib_dir, "*.so.*"))
+        ]
+        for lib_path in lib_paths:
+            dest_path = os.path.join(self.dest_libdir(),
+                                     os.path.basename(lib_path))
+            try:
+                os.unlink(dest_path)
+            except OSError as exception:
+                if exception.errno != errno.ENOENT:
+                    raise
+            if os.path.islink(lib_path):
+                if self._verbose:
+                    print("linking %s" % os.path.basename(lib_path))
+                os.symlink(os.readlink(lib_path), dest_path)
+            elif os.path.isfile(lib_path):
+                if self._verbose:
+                    print("copying %s" % os.path.basename(lib_path))
+                shutil.copy(lib_path, dest_path)
 
-    dpkg_arch = self.shell_call("dpkg-architecture -qDEB_HOST_MULTIARCH").strip()
-    lib_dirs = [
-      "usr/lib/%s" % dpkg_arch,
-      "lib/%s" % dpkg_arch,
-    ]
-    lib_paths = [path for lib_dir in lib_dirs for path in
-                 glob.glob(os.path.join(self.temp_dir(), lib_dir, "*.so.*"))]
-    for lib_path in lib_paths:
-      dest_path = os.path.join(self.dest_libdir(), os.path.basename(lib_path))
-      try:
-        os.unlink(dest_path)
-      except OSError as exception:
-        if exception.errno != errno.ENOENT:
-          raise
-      if os.path.islink(lib_path):
-        if self._verbose:
-          print('linking %s' % os.path.basename(lib_path))
-        os.symlink(os.readlink(lib_path), dest_path)
-      elif os.path.isfile(lib_path):
-        if self._verbose:
-          print('copying %s' % os.path.basename(lib_path))
-        shutil.copy(lib_path, dest_path)
+    def get_deb_files(self):
+        deb_files = []
+        files_file = os.path.join(self._source_dir, "debian/files")
 
+        for line in open(files_file, "r").read().splitlines():
+            filename, category, section = line.split(" ")
+            if not filename.endswith(".deb"):
+                continue
+            pathname = os.path.join(self._source_dir, "..", filename)
+            deb_files.append(pathname)
 
-  def get_deb_files(self):
-    deb_files = []
-    files_file = os.path.join(self._source_dir, 'debian/files')
-
-    for line in open(files_file, 'r').read().splitlines():
-      filename, category, section = line.split(' ')
-      if not filename.endswith('.deb'):
-        continue
-      pathname = os.path.join(self._source_dir, '..', filename)
-      deb_files.append(pathname)
-
-    return deb_files
+        return deb_files
 
 
 class LibcapBuilder(InstrumentedPackageBuilder):
-  def build_and_install(self):
-    # libcap2 doesn't have a configure script
-    build_args = ['CC', 'CXX', 'CFLAGS', 'CXXFLAGS', 'LDFLAGS']
-    make_args = [
-        '%s="%s"' % (name, self._build_env[name]) for name in build_args
-    ]
-    self.make(make_args)
+    def build_and_install(self):
+        # libcap2 doesn't have a configure script
+        build_args = ["CC", "CXX", "CFLAGS", "CXXFLAGS", "LDFLAGS"]
+        make_args = [
+            "%s=%s" % (name, self._build_env[name]) for name in build_args
+        ]
+        self.make(make_args)
 
-    install_args = [
-        'DESTDIR=%s' % self.temp_dir(),
-        'lib=%s' % self._libdir,
-        # Skip a step that requires sudo.
-        'RAISE_SETFCAP=no'
-    ]
-    self.make_install(install_args)
+        install_args = [
+            "DESTDIR=%s" % self.temp_dir(),
+            "lib=%s" % self._libdir,
+            # Skip a step that requires sudo.
+            "RAISE_SETFCAP=no",
+        ]
+        self.make_install(install_args)
 
-    self.cleanup_after_install()
+        self.cleanup_after_install()
 
-    self.fix_rpaths(self.temp_libdir())
+        self.fix_rpaths(self.temp_libdir())
 
-    # Now move the contents of the temporary destdir to their final place.
-    # We only care for the contents of LIBDIR.
-    self.shell_call('cp %s/* %s/ -rdf' % (self.temp_libdir(),
-                                          self.dest_libdir()))
+        # Now move the contents of the temporary destdir to their final place.
+        # We only care for the contents of LIBDIR.
+        self.shell_call("cp %s/* %s/ -rdf" %
+                        (self.temp_libdir(), self.dest_libdir()),
+                        shell=True)
 
 
 class LibcurlBuilder(DebianBuilder):
-  def build_and_install(self):
-    super().build_and_install()
-    # The libcurl packages don't specify a default libcurl.so, but this is
-    # required since libcurl.so is dlopen()ed by crashpad.  Normally,
-    # libcurl.so is installed by one of libcurl-{gnutls,nss,openssl}-dev.
-    # Doing a standalone instrumented build of a dev package is tricky,
-    # so we manually symlink libcurl.so instead.
-    libcurl_so = os.path.join(self.dest_libdir(), 'libcurl.so')
-    if not os.path.exists(libcurl_so):
-      os.symlink('libcurl.so.4', libcurl_so)
+    def build_and_install(self):
+        super().build_and_install()
+        # The libcurl packages don't specify a default libcurl.so, but this is
+        # required since libcurl.so is dlopen()ed by crashpad.  Normally,
+        # libcurl.so is installed by one of libcurl-{gnutls,nss,openssl}-dev.
+        # Doing a standalone instrumented build of a dev package is tricky,
+        # so we manually symlink libcurl.so instead.
+        libcurl_so = os.path.join(self.dest_libdir(), "libcurl.so")
+        if not os.path.exists(libcurl_so):
+            os.symlink("libcurl.so.4", libcurl_so)
 
 
 class Libpci3Builder(InstrumentedPackageBuilder):
-  def package_version(self):
-    """Guesses libpci3 version from source directory name."""
-    dir_name = os.path.split(os.path.normpath(self._source_dir))[-1]
-    match = re.match('pciutils-(\d+\.\d+\.\d+)', dir_name)
-    if match is None:
-      raise Exception(
-          'Unable to guess libpci3 version from directory name: %s' %  dir_name)
-    return match.group(1)
+    def package_version(self):
+        """Guesses libpci3 version from source directory name."""
+        dir_name = os.path.split(os.path.normpath(self._source_dir))[-1]
+        match = re.match("pciutils-(\d+\.\d+\.\d+)", dir_name)
+        if match is None:
+            raise Exception(
+                "Unable to guess libpci3 version from directory name: %s" %
+                dir_name)
+        return match.group(1)
 
-  def temp_libdir(self):
-    # DSOs have to be picked up from <source_dir>/lib, since `make install'
-    # doesn't actualy install them anywhere.
-    return os.path.join(self._source_dir, 'lib')
+    def temp_libdir(self):
+        # DSOs have to be picked up from <source_dir>/lib, since `make install'
+        # doesn't actualy install them anywhere.
+        return os.path.join(self._source_dir, "lib")
 
-  def build_and_install(self):
-    # pciutils doesn't have a configure script
-    # This build process follows debian/rules.
-    self.shell_call('mkdir -p %s-udeb/usr/bin' % self.temp_dir())
+    def build_and_install(self):
+        # pciutils doesn't have a configure script
+        # This build process follows debian/rules.
+        self.shell_call(["mkdir", "-p", "%s-udeb/usr/bin" % self.temp_dir()])
 
-    build_args = ['CC', 'CXX', 'CFLAGS', 'CXXFLAGS', 'LDFLAGS']
-    make_args = [
-        '%s="%s"' % (name, self._build_env[name]) for name in build_args
-    ]
-    make_args += [
-        'LIBDIR=/%s/' % self._libdir,
-        'PREFIX=/usr',
-        'SBINDIR=/usr/bin',
-        'IDSDIR=/usr/share/misc',
-        'SHARED=yes',
-        # pciutils fails to build due to unresolved libkmod symbols. The binary
-        # package has no dependencies on libkmod, so it looks like it was
-        # actually built without libkmod support.
-       'LIBKMOD=no',
-    ]
-    self.make(make_args)
+        build_args = ["CC", "CXX", "CFLAGS", "CXXFLAGS", "LDFLAGS"]
+        make_args = [
+            "%s=%s" % (name, self._build_env[name]) for name in build_args
+        ]
+        make_args += [
+            "LIBDIR=/%s/" % self._libdir,
+            "PREFIX=/usr",
+            "SBINDIR=/usr/bin",
+            "IDSDIR=/usr/share/misc",
+            "SHARED=yes",
+            # pciutils fails to build due to unresolved libkmod symbols. The binary
+            # package has no dependencies on libkmod, so it looks like it was
+            # actually built without libkmod support.
+            "LIBKMOD=no",
+        ]
+        self.make(make_args)
 
-    # `make install' is not needed.
-    self.fix_rpaths(self.temp_libdir())
+        # `make install' is not needed.
+        self.fix_rpaths(self.temp_libdir())
 
-    # Now install the DSOs to their final place.
-    self.shell_call(
-        'install -m 644 %s/libpci.so* %s' % (self.temp_libdir(),
-                                             self.dest_libdir()))
-    self.shell_call(
-        'ln -sf libpci.so.%s %s/libpci.so.3' % (self.package_version(),
-                                                self.dest_libdir()))
+        # Now install the DSOs to their final place.
+        self.shell_call(
+            "install -m 644 %s/libpci.so* %s" %
+            (self.temp_libdir(), self.dest_libdir()),
+            shell=True,
+        )
+        self.shell_call(
+            "ln -sf libpci.so.%s %s/libpci.so.3" %
+            (self.package_version(), self.dest_libdir()),
+            shell=True,
+        )
 
 
 class MesonBuilder(InstrumentedPackageBuilder):
-  def build_and_install(self):
-    meson_flags = {
-      'prefix': '/',
-      'libdir': self._libdir,
-      'sbindir': 'bin',
-    }
-    meson_cmd = [
-      'meson',
-      'build',
-      '.',
-      ' '.join('--%s %s' % item for item in meson_flags.items()),
-      '-Db_lundef=false',
-      self._extra_configure_flags,
-    ]
+    def build_and_install(self):
+        meson_cmd = [
+            "meson",
+            "build",
+            ".",
+            "--prefix",
+            "/",
+            "--libdir",
+            self._libdir,
+            "--sbindir",
+            "bin",
+            "-Db_lundef=false",
+        ] + self._extra_configure_flags
 
-    self.shell_call(' '.join(meson_cmd),
-                    env=self._build_env, cwd=self._source_dir)
-    self.shell_call('ninja -C build install',
-                    {**self._build_env, 'DESTDIR': self.temp_dir()},
-                    cwd=self._source_dir)
-    self.post_install()
+        self.shell_call(meson_cmd, env=self._build_env, cwd=self._source_dir)
+        self.shell_call(
+            ["ninja", "-C", "build", "install"],
+            {
+                **self._build_env, "DESTDIR": self.temp_dir()
+            },
+            cwd=self._source_dir,
+        )
+        self.post_install()
 
 
 class CmakeBuilder(InstrumentedPackageBuilder):
-  def build_and_install(self):
-    cmake_cmd = [
-      'cmake',
-      '.',
-      '-DCMAKE_INSTALL_PREFIX=/usr',
-      '-DCMAKE_INSTALL_LIBDIR=/%s/' % self._libdir,
-      self._extra_configure_flags,
-    ]
-    self.shell_call(' '.join(cmake_cmd), env=self._build_env,
-                    cwd=self._source_dir)
+    def build_and_install(self):
+        cmake_cmd = [
+            "cmake",
+            ".",
+            "-DCMAKE_INSTALL_PREFIX=/usr",
+            "-DCMAKE_INSTALL_LIBDIR=/%s/" % self._libdir,
+        ] + self._extra_configure_flags
+        self.shell_call(cmake_cmd, env=self._build_env, cwd=self._source_dir)
 
-    args = ['DESTDIR', 'BUILDROOT', 'INSTALL_ROOT']
-    make_args = ['%s=%s' % (name, self.temp_dir()) for name in args]
-    self.make(make_args)
-    self.make_install(make_args)
+        args = ["DESTDIR", "BUILDROOT", "INSTALL_ROOT"]
+        make_args = ["%s=%s" % (name, self.temp_dir()) for name in args]
+        self.make(make_args)
+        self.make_install(make_args)
 
-    self.post_install()
+        self.post_install()
 
 
 class NSSBuilder(InstrumentedPackageBuilder):
-  def build_and_install(self):
-    # NSS uses a build system that's different from configure/make/install. All
-    # flags must be passed as arguments to make.
-    make_args = [
-        # Do an optimized build.
-        'BUILD_OPT=1',
-        # CFLAGS/CXXFLAGS should not be used, as doing so overrides the flags in
-        # the makefile completely. The only way to append our flags is to tack
-        # them onto CC/CXX.
-        'CC="%s %s"' % (self._build_env['CC'], self._build_env['CFLAGS']),
-        'CXX="%s %s"' % (self._build_env['CXX'], self._build_env['CXXFLAGS']),
-        # We need to override ZDEFS_FLAG at least to avoid -Wl,-z,defs, which
-        # is not compatible with sanitizers. We also need some way to pass
-        # LDFLAGS without overriding the defaults. Conveniently, ZDEF_FLAG is
-        # always appended to link flags when building NSS on Linux, so we can
-        # just add our LDFLAGS here.
-        'ZDEFS_FLAG="-Wl,-z,nodefs %s"' % self._build_env['LDFLAGS'],
-        'NSPR_INCLUDE_DIR=/usr/include/nspr',
-        'NSPR_LIB_DIR=%s' % self.dest_libdir(),
-        'NSS_ENABLE_ECC=1'
-    ]
-    if platform.architecture()[0] == '64bit':
-      make_args.append('USE_64=1')
+    def build_and_install(self):
+        # NSS uses a build system that's different from configure/make/install. All
+        # flags must be passed as arguments to make.
+        make_args = [
+            # Do an optimized build.
+            "BUILD_OPT=1",
+            # CFLAGS/CXXFLAGS should not be used, as doing so overrides the flags in
+            # the makefile completely. The only way to append our flags is to tack
+            # them onto CC/CXX.
+            'CC="%s %s"' % (self._build_env["CC"], self._build_env["CFLAGS"]),
+            'CXX="%s %s"' %
+            (self._build_env["CXX"], self._build_env["CXXFLAGS"]),
+            # We need to override ZDEFS_FLAG at least to avoid -Wl,-z,defs, which
+            # is not compatible with sanitizers. We also need some way to pass
+            # LDFLAGS without overriding the defaults. Conveniently, ZDEF_FLAG is
+            # always appended to link flags when building NSS on Linux, so we can
+            # just add our LDFLAGS here.
+            'ZDEFS_FLAG="-Wl,-z,nodefs %s"' % self._build_env["LDFLAGS"],
+            "NSPR_INCLUDE_DIR=/usr/include/nspr",
+            "NSPR_LIB_DIR=%s" % self.dest_libdir(),
+            "NSS_ENABLE_ECC=1",
+        ]
+        if platform.architecture()[0] == "64bit":
+            make_args.append("USE_64=1")
 
-    # Make sure we don't override the default flags in the makefile.
-    for variable in ['CFLAGS', 'CXXFLAGS', 'LDFLAGS']:
-      del self._build_env[variable]
+        # Make sure we don't override the default flags in the makefile.
+        for variable in ["CFLAGS", "CXXFLAGS", "LDFLAGS"]:
+            del self._build_env[variable]
 
-    # Hardcoded paths.
-    temp_dir = os.path.join(self._source_dir, 'nss')
-    temp_libdir = os.path.join(temp_dir, 'lib')
+        # Hardcoded paths.
+        temp_dir = os.path.join(self._source_dir, "nss")
+        temp_libdir = os.path.join(temp_dir, "lib")
 
-    # The build happens in <source_dir>/nss.  Building fails after all
-    # the required DSOs have been built, so ignore the error.
-    self.make(make_args, cwd=temp_dir, ignore_ret_code=True)
+        # The build happens in <source_dir>/nss.  Building fails after all
+        # the required DSOs have been built, so ignore the error.
+        self.make(make_args, cwd=temp_dir, ignore_ret_code=True)
 
-    self.fix_rpaths(temp_libdir)
+        self.fix_rpaths(temp_libdir)
 
-    # 'make install' is not supported. Copy the DSOs manually.
-    for (dirpath, dirnames, filenames) in os.walk(temp_libdir):
-      for filename in filenames:
-        if filename.endswith('.so'):
-          full_path = os.path.join(dirpath, filename)
-          if self._verbose:
-            print('download_build_install.py: installing ' + full_path)
-          shutil.copy(full_path, self.dest_libdir())
-
-
-class ZlibBuilder(InstrumentedPackageBuilder):
-  def build_and_install(self):
-    super().build_and_install(['libz.so.1.2.11'])
+        # 'make install' is not supported. Copy the DSOs manually.
+        for (dirpath, dirnames, filenames) in os.walk(temp_libdir):
+            for filename in filenames:
+                if filename.endswith(".so"):
+                    full_path = os.path.join(dirpath, filename)
+                    if self._verbose:
+                        print("download_build_install.py: installing " +
+                              full_path)
+                    shutil.copy(full_path, self.dest_libdir())
 
 
 class StubBuilder(InstrumentedPackageBuilder):
-  def download_build_install(self):
-    self._touch(os.path.join(self._destdir, '%s.txt' % self._package))
-    self.shell_call('mkdir -p %s' % self.dest_libdir())
-    self._touch(os.path.join(self.dest_libdir(), '%s.so.0' % self._package))
+    def download_build_install(self):
+        self._touch(os.path.join(self._destdir, "%s.txt" % self._package))
+        self.shell_call(["mkdir", "-p", self.dest_libdir()])
+        self._touch(os.path.join(self.dest_libdir(),
+                                 "%s.so.0" % self._package))
 
-  def _touch(self, path):
-    with open(path, 'w'):
-      pass
+    def _touch(self, path):
+        with open(path, "w"):
+            pass
 
 
 def main():
-  parser = argparse.ArgumentParser(
-      description='Download, build and install an instrumented package.')
+    parser = argparse.ArgumentParser(
+        description="Download, build and install an instrumented package.")
 
-  parser.add_argument('-p', '--package', required=True)
-  parser.add_argument(
-      '-i', '--product-dir', default='.',
-      help='Relative path to the directory with chrome binaries')
-  parser.add_argument(
-      '-m', '--intermediate-dir', default='.',
-      help='Relative path to the directory for temporary build files')
-  parser.add_argument('--extra-configure-flags', default='')
-  parser.add_argument('--cflags', default='')
-  parser.add_argument('--ldflags', default='')
-  parser.add_argument('-v', '--verbose', action='store_true')
-  parser.add_argument('--cc')
-  parser.add_argument('--cxx')
-  parser.add_argument('--patch', nargs='*', action='extend', default=[])
-  # This should be a shell script to run before building specific libraries.
-  # This will be run after applying the patches above.
-  parser.add_argument('--pre-build', default='')
-  parser.add_argument('--build-method', default='destdir')
-  parser.add_argument('--sanitizer-ignorelist', default='')
-  # The LIBDIR argument to configure/make.
-  parser.add_argument('--libdir', default='lib')
-  parser.add_argument('--env', default='')
-  parser.add_argument('--git-url', default='')
-  parser.add_argument('--git-revision', default='')
-  parser.add_argument('--no-configure', action='store_true')
+    parser.add_argument("-p", "--package", required=True)
+    parser.add_argument(
+        "-i",
+        "--product-dir",
+        default=".",
+        help="Relative path to the directory with chrome binaries",
+    )
+    parser.add_argument(
+        "-m",
+        "--intermediate-dir",
+        default=".",
+        help="Relative path to the directory for temporary build files",
+    )
+    parser.add_argument("--extra-configure-flags", default="")
+    parser.add_argument("--cflags", default="")
+    parser.add_argument("--ldflags", default="")
+    parser.add_argument("-v", "--verbose", action="store_true")
+    parser.add_argument("--cc")
+    parser.add_argument("--cxx")
+    parser.add_argument("--patch", nargs="*", action="extend", default=[])
+    # This should be a shell script to run before building specific libraries.
+    # This will be run after applying the patches above.
+    parser.add_argument("--pre-build", default="")
+    parser.add_argument("--build-method", default="destdir")
+    parser.add_argument("--sanitizer-ignorelist", default="")
+    # The LIBDIR argument to configure/make.
+    parser.add_argument("--libdir", default="lib")
+    parser.add_argument("--env", default="")
+    parser.add_argument("--git-url", default="")
+    parser.add_argument("--git-revision", default="")
+    parser.add_argument("--make-targets", default="")
 
-  # Ignore all empty arguments because in several cases gyp passes them to the
-  # script, but ArgumentParser treats them as positional arguments instead of
-  # ignoring (and doesn't have such options).
-  args = parser.parse_args([arg for arg in sys.argv[1:] if len(arg) != 0])
+    # Ignore all empty arguments because in several cases gn passes them to the
+    # script, but ArgumentParser treats them as positional arguments instead of
+    # ignoring (and doesn't have such options).
+    args = parser.parse_args([arg for arg in sys.argv[1:] if len(arg) != 0])
 
-  # Clobber by default, unless the developer wants to hack on the package's
-  # source code.
-  clobber = \
-        (os.environ.get('INSTRUMENTED_LIBRARIES_NO_CLOBBER', '') != '1')
+    # Clobber by default, unless the developer wants to hack on the package's
+    # source code.
+    clobber = os.environ.get("INSTRUMENTED_LIBRARIES_NO_CLOBBER", "") != "1"
 
-  if args.build_method == 'destdir':
-    builder = InstrumentedPackageBuilder(args, clobber)
-  elif args.build_method == 'custom_nss':
-    builder = NSSBuilder(args, clobber)
-  elif args.build_method == 'custom_libcap':
-    builder = LibcapBuilder(args, clobber)
-  elif args.build_method == 'custom_libcurl':
-    builder = LibcurlBuilder(args, clobber)
-  elif args.build_method == 'custom_libpci3':
-    builder = Libpci3Builder(args, clobber)
-  elif args.build_method == 'custom_zlib':
-    builder = ZlibBuilder(args, clobber)
-  elif args.build_method == 'debian':
-    builder = DebianBuilder(args, clobber)
-  elif args.build_method == 'meson':
-    builder = MesonBuilder(args, clobber)
-  elif args.build_method == 'cmake':
-    builder = CmakeBuilder(args, clobber)
-  elif args.build_method == 'stub':
-    builder = StubBuilder(args, clobber)
-  else:
-    raise Exception('Unrecognized build method: %s' % args.build_method)
+    if args.build_method == "destdir":
+        builder = InstrumentedPackageBuilder(args, clobber)
+    elif args.build_method == "custom_nss":
+        builder = NSSBuilder(args, clobber)
+    elif args.build_method == "custom_libcap":
+        builder = LibcapBuilder(args, clobber)
+    elif args.build_method == "custom_libcurl":
+        builder = LibcurlBuilder(args, clobber)
+    elif args.build_method == "custom_libpci3":
+        builder = Libpci3Builder(args, clobber)
+    elif args.build_method == "debian":
+        builder = DebianBuilder(args, clobber)
+    elif args.build_method == "meson":
+        builder = MesonBuilder(args, clobber)
+    elif args.build_method == "cmake":
+        builder = CmakeBuilder(args, clobber)
+    elif args.build_method == "stub":
+        builder = StubBuilder(args, clobber)
+    else:
+        raise Exception("Unrecognized build method: %s" % args.build_method)
 
-  builder.download_build_install()
+    builder.download_build_install()
 
-if __name__ == '__main__':
-  main()
+
+if __name__ == "__main__":
+    main()
diff --git a/third_party/instrumented_libraries/focal/scripts/fix_rpaths.sh b/third_party/instrumented_libraries/focal/scripts/fix_rpaths.sh
index 6b2a0df..94bb445 100755
--- a/third_party/instrumented_libraries/focal/scripts/fix_rpaths.sh
+++ b/third_party/instrumented_libraries/focal/scripts/fix_rpaths.sh
@@ -4,7 +4,7 @@
 # found in the LICENSE file.
 
 # Changes all RPATHs in a given directory from XORIGIN to $ORIGIN
-# See the comment about XORIGIN in instrumented_libraries.gyp
+# See the comment about XORIGIN in BUILD.gn
 
 # Fixes rpath from XORIGIN to $ORIGIN in a single file $1.
 function fix_rpath {
diff --git a/third_party/instrumented_libraries/focal/scripts/pre-build/autogen.sh b/third_party/instrumented_libraries/focal/scripts/pre-build/autogen.sh
index 7ebab4e2..96715952 100755
--- a/third_party/instrumented_libraries/focal/scripts/pre-build/autogen.sh
+++ b/third_party/instrumented_libraries/focal/scripts/pre-build/autogen.sh
@@ -11,7 +11,7 @@
 # as that sometimes breaks build. Which is why we have this file.
 
 # Also, some packages may or may not have an autogen script, depending on
-# version. Rather than clutter the GYP file with conditionals, we simply do
+# version. Rather than clutter the GN file with conditionals, we simply do
 # nothing if the file is not present.
 
 if [ -x ./autogen.sh ]
diff --git a/third_party/instrumented_libraries/scripts/build_and_package.py b/third_party/instrumented_libraries/scripts/build_and_package.py
index fe1d0bf..7229523 100755
--- a/third_party/instrumented_libraries/scripts/build_and_package.py
+++ b/third_party/instrumented_libraries/scripts/build_and_package.py
@@ -10,125 +10,133 @@
 import subprocess
 import tarfile
 
-
 BUILD_TYPES = {
-    'msan-no-origins': [
-        'is_msan = true',
-        'msan_track_origins = 0',
+    "msan-no-origins": [
+        "is_msan = true",
+        "msan_track_origins = 0",
     ],
-    'msan-chained-origins': [
-        'is_msan = true',
-        'msan_track_origins = 2',
+    "msan-chained-origins": [
+        "is_msan = true",
+        "msan_track_origins = 2",
     ],
 }
 
 
 class Error(Exception):
-  pass
+    pass
 
 
 class IncorrectReleaseError(Error):
-  pass
+    pass
 
 
 def _get_release():
-  return subprocess.check_output(['lsb_release', '-cs']).decode('utf-8').strip()
+    return subprocess.check_output(["lsb_release",
+                                    "-cs"]).decode("utf-8").strip()
 
 
 def _tar_filter(tar_info):
-  if tar_info.name.endswith('.txt'):
-    return None
-  return tar_info
+    if tar_info.name.endswith(".txt"):
+        return None
+    return tar_info
 
 
 def build_libraries(build_type, ubuntu_release, jobs, use_goma):
-  build_dir = 'out/Instrumented-%s' % build_type
-  if not os.path.exists(build_dir):
-    os.makedirs(build_dir)
+    build_dir = "out/Instrumented-%s" % build_type
+    if not os.path.exists(build_dir):
+        os.makedirs(build_dir)
 
-  gn_args = [
-      'is_debug = false',
-      'use_goma = %s' % str(use_goma).lower(),
-      'use_locally_built_instrumented_libraries = true',
-      'instrumented_libraries_release = "%s"' % ubuntu_release,
-  ] + BUILD_TYPES[build_type]
-  with open(os.path.join(build_dir, 'args.gn'), 'w') as f:
-    f.write('\n'.join(gn_args) + '\n')
-  subprocess.check_call(['gn', 'gen', build_dir, '--check'])
-  subprocess.check_call([
-      'ninja',
-      '-j%d' % jobs, '-C', build_dir,
-      'third_party/instrumented_libraries/%s:locally_built' % ubuntu_release
-  ])
-  with tarfile.open('%s.tgz' % build_type, mode='w:gz') as f:
-    f.add(
-        '%s/instrumented_libraries/lib' % build_dir,
-        arcname='lib',
-        filter=_tar_filter)
-    f.add(
-        '%s/instrumented_libraries/sources' % build_dir,
-        arcname='sources',
-        filter=_tar_filter)
+    gn_args = [
+        "is_debug = false",
+        "use_goma = %s" % str(use_goma).lower(),
+        "use_locally_built_instrumented_libraries = true",
+        'instrumented_libraries_release = "%s"' % ubuntu_release,
+    ] + BUILD_TYPES[build_type]
+    with open(os.path.join(build_dir, "args.gn"), "w") as f:
+        f.write("\n".join(gn_args) + "\n")
+    subprocess.check_call(["gn", "gen", build_dir, "--check"])
+    subprocess.check_call([
+        "ninja",
+        "-j%d" % jobs,
+        "-C",
+        build_dir,
+        "third_party/instrumented_libraries/%s:locally_built" % ubuntu_release,
+    ])
+    with tarfile.open("%s.tgz" % build_type, mode="w:gz") as f:
+        f.add(
+            "%s/instrumented_libraries/lib" % build_dir,
+            arcname="lib",
+            filter=_tar_filter,
+        )
+        f.add(
+            "%s/instrumented_libraries/sources" % build_dir,
+            arcname="sources",
+            filter=_tar_filter,
+        )
 
 
 def main():
-  parser = argparse.ArgumentParser(
-      description=__doc__,
-      formatter_class=argparse.ArgumentDefaultsHelpFormatter)
-  parser.add_argument(
-      '--jobs',
-      '-j',
-      type=int,
-      default=8,
-      help='the default number of jobs to use when running ninja')
-  parser.add_argument(
-      '--parallel',
-      action='store_true',
-      default=False,
-      help='whether to run all instrumented builds in parallel')
-  parser.add_argument(
-      '--use_goma',
-      action='store_true',
-      default=False,
-      help='whether to use goma to compile')
-  parser.add_argument(
-      'build_type',
-      nargs='*',
-      default='all',
-      choices=list(BUILD_TYPES.keys()) + ['all'],
-      help='the type of instrumented library to build')
-  parser.add_argument(
-      'release', help='the name of the Ubuntu release to build with')
-  args = parser.parse_args()
-  if args.build_type == 'all' or 'all' in args.build_type:
-    args.build_type = BUILD_TYPES.keys()
+    parser = argparse.ArgumentParser(
+        description=__doc__,
+        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+    parser.add_argument(
+        "--jobs",
+        "-j",
+        type=int,
+        default=8,
+        help="the default number of jobs to use when running ninja",
+    )
+    parser.add_argument(
+        "--parallel",
+        action="store_true",
+        default=False,
+        help="whether to run all instrumented builds in parallel",
+    )
+    parser.add_argument(
+        "--use_goma",
+        action="store_true",
+        default=False,
+        help="whether to use goma to compile",
+    )
+    parser.add_argument(
+        "build_type",
+        nargs="*",
+        default="all",
+        choices=list(BUILD_TYPES.keys()) + ["all"],
+        help="the type of instrumented library to build",
+    )
+    parser.add_argument("release",
+                        help="the name of the Ubuntu release to build with")
+    args = parser.parse_args()
+    if args.build_type == "all" or "all" in args.build_type:
+        args.build_type = BUILD_TYPES.keys()
 
-  if args.release != _get_release():
-    raise IncorrectReleaseError(
-        'trying to build for %s but the current release is %s' %
-        (args.release, _get_release()))
-  build_types = sorted(set(args.build_type))
-  if args.parallel:
-    procs = []
+    if args.release != _get_release():
+        raise IncorrectReleaseError(
+            "trying to build for %s but the current release is %s" %
+            (args.release, _get_release()))
+    build_types = sorted(set(args.build_type))
+    if args.parallel:
+        procs = []
+        for build_type in build_types:
+            proc = multiprocessing.Process(
+                target=build_libraries,
+                args=(build_type, args.release, args.jobs, args.use_goma),
+            )
+            proc.start()
+            procs.append(proc)
+        for proc in procs:
+            proc.join()
+    else:
+        for build_type in build_types:
+            build_libraries(build_type, args.release, args.jobs, args.use_goma)
+    print("To upload, run:")
     for build_type in build_types:
-      proc = multiprocessing.Process(
-          target=build_libraries,
-          args=(build_type, args.release, args.jobs, args.use_goma))
-      proc.start()
-      procs.append(proc)
-    for proc in procs:
-      proc.join()
-  else:
-    for build_type in build_types:
-      build_libraries(build_type, args.release, args.jobs, args.use_goma)
-  print('To upload, run:')
-  for build_type in build_types:
-    print(
-        'upload_to_google_storage.py -b '
-        'chromium-instrumented-libraries %s-%s.tgz' %
-        (build_type, args.release))
-  print('You should then commit the resulting .sha1 files.')
+        print("upload_to_google_storage.py -b "
+              "chromium-instrumented-libraries %s-%s.tgz" %
+              (build_type, args.release))
+    print("You should then commit the resulting .sha1 files.")
 
 
-if __name__ == '__main__':
-  main()
+if __name__ == "__main__":
+    main()
diff --git a/third_party/instrumented_libraries/scripts/unpack_binaries.py b/third_party/instrumented_libraries/scripts/unpack_binaries.py
index 0f791d1..d485d4b 100755
--- a/third_party/instrumented_libraries/scripts/unpack_binaries.py
+++ b/third_party/instrumented_libraries/scripts/unpack_binaries.py
@@ -2,7 +2,6 @@
 # Copyright 2015 The Chromium Authors
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
-
 """Unpacks pre-built sanitizer-instrumented third-party libraries."""
 
 import os
@@ -12,29 +11,33 @@
 
 
 def get_archive_name(archive_prefix, release):
-  return '%s-%s.tgz' % (archive_prefix, release)
+    return "%s-%s.tgz" % (archive_prefix, release)
 
 
 def main(archive_prefix, release, archive_dir, target_dir, stamp_dir=None):
-  shutil.rmtree(target_dir, ignore_errors=True)
+    shutil.rmtree(target_dir, ignore_errors=True)
 
-  os.mkdir(target_dir)
-  subprocess.check_call([
-      'tar',
-      '-zxf',
-      os.path.join(archive_dir, get_archive_name(archive_prefix, release)),
-      '-C',
-      target_dir])
-  stamp_file = os.path.join(stamp_dir or target_dir, '%s.txt' % archive_prefix)
-  open(stamp_file, 'w').close()
+    os.mkdir(target_dir)
+    subprocess.check_call([
+        "tar",
+        "-zxf",
+        os.path.join(archive_dir, get_archive_name(archive_prefix, release)),
+        "-C",
+        target_dir,
+    ])
+    stamp_file = os.path.join(stamp_dir or target_dir,
+                              "%s.txt" % archive_prefix)
+    open(stamp_file, "w").close()
 
-  if stamp_dir:
-    with open(os.path.join(stamp_dir, '%s.d' % archive_prefix), 'w') as f:
-      f.write('%s: %s' % (
-          stamp_file, os.path.join(archive_dir,
-                                   get_archive_name(archive_prefix, release))))
-  return 0
+    if stamp_dir:
+        with open(os.path.join(stamp_dir, "%s.d" % archive_prefix), "w") as f:
+            f.write("%s: %s" % (
+                stamp_file,
+                os.path.join(archive_dir,
+                             get_archive_name(archive_prefix, release)),
+            ))
+    return 0
 
 
-if __name__ == '__main__':
-  sys.exit(main(*sys.argv[1:]))
+if __name__ == "__main__":
+    sys.exit(main(*sys.argv[1:]))
diff --git a/third_party/libc++/src b/third_party/libc++/src
index d781e6e..2364ae8 160000
--- a/third_party/libc++/src
+++ b/third_party/libc++/src
@@ -1 +1 @@
-Subproject commit d781e6e1b823d1391179f52516e0fc93e61567b2
+Subproject commit 2364ae8b073e44c9ac2725e176f2ce57967f1012
diff --git a/third_party/opus/tests/opus_benchmark.cc b/third_party/opus/tests/opus_benchmark.cc
index 180d58c..f7640bf 100644
--- a/third_party/opus/tests/opus_benchmark.cc
+++ b/third_party/opus/tests/opus_benchmark.cc
@@ -8,6 +8,7 @@
 #include <ctime>
 #include <limits>
 
+#include "base/check.h"
 #include "base/files/file_path.h"
 #include "base/path_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/third_party/pdfium b/third_party/pdfium
index 0a34b6b..6a34da3 160000
--- a/third_party/pdfium
+++ b/third_party/pdfium
@@ -1 +1 @@
-Subproject commit 0a34b6b287747f2911474375ab7d3d7367d9e049
+Subproject commit 6a34da391b15f5373247fda48c10a12bc4143c94
diff --git a/third_party/perfetto b/third_party/perfetto
index 33063c94..6f755e2 160000
--- a/third_party/perfetto
+++ b/third_party/perfetto
@@ -1 +1 @@
-Subproject commit 33063c9403c381f5411e1cddf8688a912529b4d9
+Subproject commit 6f755e28a296d022cb03c3843ea6cc2c45176778
diff --git a/third_party/skia b/third_party/skia
index 2b21838..e3cf4d9 160000
--- a/third_party/skia
+++ b/third_party/skia
@@ -1 +1 @@
-Subproject commit 2b218381e226d986a9b43789d8822b1ce4d80516
+Subproject commit e3cf4d9ffc3841d7b032e2549204bcceddd0946a
diff --git a/third_party/webgpu-cts/src b/third_party/webgpu-cts/src
index 1c407e09..149e02a 160000
--- a/third_party/webgpu-cts/src
+++ b/third_party/webgpu-cts/src
@@ -1 +1 @@
-Subproject commit 1c407e0944032ac9877bf4e5e000acff7a591b73
+Subproject commit 149e02ab793f6a323a5ea4a3d2f52547aefc1434
diff --git a/third_party/webgpu-cts/ts_sources.txt b/third_party/webgpu-cts/ts_sources.txt
index 4f0cdea..4132a0bc 100644
--- a/third_party/webgpu-cts/ts_sources.txt
+++ b/third_party/webgpu-cts/ts_sources.txt
@@ -332,6 +332,7 @@
 src/webgpu/api/validation/texture/float32_filterable.spec.ts
 src/webgpu/api/validation/texture/rg11b10ufloat_renderable.spec.ts
 src/webgpu/compat/compatibility_test.ts
+src/webgpu/compat/api/validation/createBindGroup.spec.ts
 src/webgpu/compat/api/validation/encoding/cmds/copyTextureToBuffer.spec.ts
 src/webgpu/compat/api/validation/encoding/programmable/pipeline_bind_group_compat.spec.ts
 src/webgpu/compat/api/validation/render_pipeline/fragment_state.spec.ts
diff --git a/third_party/webrtc b/third_party/webrtc
index be04c98..bd523af 160000
--- a/third_party/webrtc
+++ b/third_party/webrtc
@@ -1 +1 @@
-Subproject commit be04c98d6488fc86594424e39c16d849f8628e27
+Subproject commit bd523afd3ab69c882e5e50a7fcc4b28bbd9e0d43
diff --git a/third_party/woff2/README.chromium b/third_party/woff2/README.chromium
index 2e5e09b2..f28f085 100644
--- a/third_party/woff2/README.chromium
+++ b/third_party/woff2/README.chromium
@@ -1,6 +1,6 @@
 Name: woff2
 URL: https://github.com/google/woff2
-Version: 4721483ad780ee2b63cb787bfee4aa64b61a0446
+Version: 0f4d304faa1c62994536dc73510305c7357da8d4
 License: MIT
 License File: LICENSE
 Security Critical: yes
diff --git a/third_party/woff2/src/store_bytes.h b/third_party/woff2/src/store_bytes.h
index fff3c62..099c0f2 100644
--- a/third_party/woff2/src/store_bytes.h
+++ b/third_party/woff2/src/store_bytes.h
@@ -27,15 +27,8 @@
 }
 
 inline size_t Store16(uint8_t* dst, size_t offset, int x) {
-#if defined(WOFF_LITTLE_ENDIAN)
-  *reinterpret_cast<uint16_t*>(dst + offset) =
-      ((x & 0xFF) << 8) | ((x & 0xFF00) >> 8);
-#elif defined(WOFF_BIG_ENDIAN)
-  *reinterpret_cast<uint16_t*>(dst + offset) = static_cast<uint16_t>(x);
-#else
   dst[offset] = x >> 8;
   dst[offset + 1] = x;
-#endif
   return offset + 2;
 }
 
@@ -47,17 +40,8 @@
 }
 
 inline void Store16(int val, size_t* offset, uint8_t* dst) {
-#if defined(WOFF_LITTLE_ENDIAN)
-  *reinterpret_cast<uint16_t*>(dst + *offset) =
-      ((val & 0xFF) << 8) | ((val & 0xFF00) >> 8);
-  *offset += 2;
-#elif defined(WOFF_BIG_ENDIAN)
-  *reinterpret_cast<uint16_t*>(dst + *offset) = static_cast<uint16_t>(val);
-  *offset += 2;
-#else
   dst[(*offset)++] = val >> 8;
   dst[(*offset)++] = val;
-#endif
 }
 
 inline void StoreBytes(const uint8_t* data, size_t len,
diff --git a/third_party/woff2/src/woff2_common.cc b/third_party/woff2/src/woff2_common.cc
index fe0a3be..a24d213 100644
--- a/third_party/woff2/src/woff2_common.cc
+++ b/third_party/woff2/src/woff2_common.cc
@@ -19,16 +19,8 @@
   uint32_t checksum = 0;
   size_t aligned_size = size & ~3;
   for (size_t i = 0; i < aligned_size; i += 4) {
-#if defined(WOFF_LITTLE_ENDIAN)
-    uint32_t v = *reinterpret_cast<const uint32_t*>(buf + i);
-    checksum += (((v & 0xFF) << 24) | ((v & 0xFF00) << 8) |
-      ((v & 0xFF0000) >> 8) | ((v & 0xFF000000) >> 24));
-#elif defined(WOFF_BIG_ENDIAN)
-    checksum += *reinterpret_cast<const uint32_t*>(buf + i);
-#else
-    checksum += (buf[i] << 24) | (buf[i + 1] << 16) |
-      (buf[i + 2] << 8) | buf[i + 3];
-#endif
+    checksum +=
+        (buf[i] << 24) | (buf[i + 1] << 16) | (buf[i + 2] << 8) | buf[i + 3];
   }
 
   // treat size not aligned on 4 as if it were padded to 4 with 0's
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index d38a3d1..66376d34 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -479,6 +479,7 @@
       # TODO(crbug.com/1235218): remove after the migration.
       'chromeos-amd64-generic-rel (reclient compare)': 'chromeos_amd64-generic-vm_use_fake_dbus_clients_reclient',
       'chromeos-amd64-generic-rel (reclient)': 'chromeos_amd64-generic-vm_use_fake_dbus_clients_reclient',
+      'chromeos-jacuzzi-rel-skylab-fyi': 'chromeos_jacuzzi_rel_skylab_reclient',
       'ios-blink-dbg-fyi': 'ios_simulator_blink_xctest',
       'ios-fieldtrial-rel': 'ios_simulator_debug_static_bot_xctest_arm64_reclient',
       'ios-m1-simulator': 'ios_simulator_debug_static_bot_xctest_arm64_reclient',
@@ -1109,6 +1110,7 @@
       'chromeos-arm-generic-rel': 'chromeos_arm-generic_dcheck_always_on_reclient',
       'chromeos-arm64-generic-rel': 'chromeos_arm64-generic_dchecks_reclient',
       'chromeos-jacuzzi-rel': 'chromeos_jacuzzi_dchecks_reclient',
+      'chromeos-jacuzzi-rel-skylab-fyi': 'chromeos_jacuzzi_rel_skylab_reclient',
       'chromeos-octopus-rel': 'chromeos_octopus_dchecks_reclient',
       'gpu-fyi-try-chromeos-amd64-generic': 'gpu_tests_chromeos_amd64_release_trybot_dcheck_off_no_symbols_reclient',
       'lacros-amd64-generic-rel': 'chromeos_amd64-generic_lacros_rel_dchecks_skylab_reclient_use_dummy_lastchange',
@@ -2343,6 +2345,10 @@
       'chromeos_device_reclient', 'jacuzzi', 'include_unwind_tables', 'official', 'is_skylab',
       'also_build_lacros_chrome_for_architecture_arm',
     ],
+    'chromeos_jacuzzi_rel_skylab_reclient': [
+      'chromeos_device', 'jacuzzi', 'include_unwind_tables',
+      'also_build_lacros_chrome_for_architecture_arm', 'is_skylab'
+    ],
 
     'chromeos_js_coverage_reclient': [
       'chromeos_with_codecs', 'release_bot_reclient', 'use_javascript_coverage', 'optimize_webui_off',
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json
index 1b69e9a..4f6a75c 100644
--- a/tools/mb/mb_config_expectations/chromium.fyi.json
+++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -395,6 +395,18 @@
       "use_remoteexec": true
     }
   },
+  "chromeos-jacuzzi-rel-skylab-fyi": {
+    "args_file": "//build/args/chromeos/jacuzzi.gni",
+    "gn_args": {
+      "also_build_lacros_chrome_for_architecture": "arm",
+      "dcheck_always_on": false,
+      "exclude_unwind_tables": false,
+      "is_chromeos_device": true,
+      "is_skylab": true,
+      "ozone_platform_headless": true,
+      "use_remoteexec": true
+    }
+  },
   "ios-blink-dbg-fyi": {
     "gn_args": {
       "dcheck_always_on": true,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json b/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json
index dac76d3..ae4a13f 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json
@@ -144,6 +144,18 @@
       "use_remoteexec": true
     }
   },
+  "chromeos-jacuzzi-rel-skylab-fyi": {
+    "args_file": "//build/args/chromeos/jacuzzi.gni",
+    "gn_args": {
+      "also_build_lacros_chrome_for_architecture": "arm",
+      "dcheck_always_on": false,
+      "exclude_unwind_tables": false,
+      "is_chromeos_device": true,
+      "is_skylab": true,
+      "ozone_platform_headless": true,
+      "use_remoteexec": true
+    }
+  },
   "chromeos-octopus-rel": {
     "args_file": "//build/args/chromeos/octopus.gni",
     "gn_args": {
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index a4e06ec..6daf9c6a 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -2457,6 +2457,14 @@
   <description>Please enter the description of this user action.</description>
 </action>
 
+<action name="Actions.PinnedToolbarButtonActivation">
+  <owner>corising@chromium.org</owner>
+  <owner>chrome-desktop-ui-sea@google.com</owner>
+  <description>
+    Recorded when an action pinned to the toolbar is activated.
+  </description>
+</action>
+
 <action name="ActiveBrowserChanged" not_user_triggered="true">
   <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
   <description>Please enter the description of this user action.</description>
@@ -32616,6 +32624,15 @@
   </description>
 </action>
 
+<action name="SidePanel.Bookmarks.Pinned.BySidePanelHeaderButton">
+  <owner>corising@chromium.org</owner>
+  <owner>chrome-desktop-ui-sea@google.com</owner>
+  <description>
+    Recorded when the bookmarks side panel entry is pinned via the pin button in
+    the side panel header.
+  </description>
+</action>
+
 <action name="SidePanel.Bookmarks.Shown">
   <owner>johntlee@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
@@ -32624,6 +32641,15 @@
   </description>
 </action>
 
+<action name="SidePanel.Bookmarks.Unpinned.BySidePanelHeaderButton">
+  <owner>corising@chromium.org</owner>
+  <owner>chrome-desktop-ui-sea@google.com</owner>
+  <description>
+    Recorded when the bookmarks side panel entry is unpinned via the pin button
+    in the side panel header.
+  </description>
+</action>
+
 <action name="SidePanel.Companion.Pinned.BySidePanelHeaderButton">
   <owner>corising@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
@@ -32659,12 +32685,32 @@
   </description>
 </action>
 
+<action name="SidePanel.Feed.Pinned.BySidePanelHeaderButton">
+  <owner>corising@chromium.org</owner>
+  <owner>jianli@chromium.org</owner>
+  <owner>chrome-desktop-ui-sea@google.com</owner>
+  <description>
+    Recorded when the feed side panel entry is pinned via the pin button in the
+    side panel header.
+  </description>
+</action>
+
 <action name="SidePanel.Feed.Shown">
   <owner>jianli@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
   <description>Recorded when the feed side panel entry is shown.</description>
 </action>
 
+<action name="SidePanel.Feed.Unpinned.BySidePanelHeaderButton">
+  <owner>corising@chromium.org</owner>
+  <owner>jianli@chromium.org</owner>
+  <owner>chrome-desktop-ui-sea@google.com</owner>
+  <description>
+    Recorded when the feed side panel entry is unpinned via the pin button in
+    the side panel header.
+  </description>
+</action>
+
 <action name="SidePanel.Hide">
   <owner>corising@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
@@ -32680,6 +32726,16 @@
   </description>
 </action>
 
+<action name="SidePanel.HistoryClusters.Pinned.BySidePanelHeaderButton">
+  <owner>corising@chromium.org</owner>
+  <owner>mfacey@chromium.org</owner>
+  <owner>chrome-desktop-ui-sea@google.com</owner>
+  <description>
+    Recorded when the history clusters side panel entry is pinned via the pin
+    button in the side panel header.
+  </description>
+</action>
+
 <action name="SidePanel.HistoryClusters.Shown">
   <owner>mfacey@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
@@ -32688,6 +32744,16 @@
   </description>
 </action>
 
+<action name="SidePanel.HistoryClusters.Unpinned.BySidePanelHeaderButton">
+  <owner>corising@chromium.org</owner>
+  <owner>mfacey@chromium.org</owner>
+  <owner>chrome-desktop-ui-sea@google.com</owner>
+  <description>
+    Recorded when the history clusters side panel entry is unpinned via the pin
+    button in the side panel header.
+  </description>
+</action>
+
 <action name="SidePanel.Lens.NewTabButtonClicked">
   <owner>lens-chrome-eng@google.com</owner>
   <owner>juanmojica@google.com</owner>
@@ -32703,6 +32769,16 @@
   <description>Recorded when the Lens side panel entry is shown.</description>
 </action>
 
+<action name="SidePanel.Performance.Pinned.BySidePanelHeaderButton">
+  <owner>corising@chromium.org</owner>
+  <owner>agale@chromium.org</owner>
+  <owner>chrome-desktop-ui-sea@google.com</owner>
+  <description>
+    Recorded when the performance side panel entry is pinned via the pin button
+    in the side panel header.
+  </description>
+</action>
+
 <action name="SidePanel.Performance.Shown">
   <owner>agale@chromium.org</owner>
   <owner>chrome-performance-ui-sea@google.com</owner>
@@ -32711,6 +32787,26 @@
   </description>
 </action>
 
+<action name="SidePanel.Performance.Unpinned.BySidePanelHeaderButton">
+  <owner>corising@chromium.org</owner>
+  <owner>agale@chromium.org</owner>
+  <owner>chrome-desktop-ui-sea@google.com</owner>
+  <description>
+    Recorded when the performance side panel entry is unpinned via the pin
+    button in the side panel header.
+  </description>
+</action>
+
+<action name="SidePanel.ReadAnything.Pinned.BySidePanelHeaderButton">
+  <owner>corising@chromium.org</owner>
+  <owner>abigailbklein@chromium.org</owner>
+  <owner>chrome-desktop-ui-sea@google.com</owner>
+  <description>
+    Recorded when the read anything side panel entry is pinned via the pin
+    button in the side panel header.
+  </description>
+</action>
+
 <action name="SidePanel.ReadAnything.Shown">
   <owner>abigailbklein@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
@@ -32719,6 +32815,16 @@
   </description>
 </action>
 
+<action name="SidePanel.ReadAnything.Unpinned.BySidePanelHeaderButton">
+  <owner>corising@chromium.org</owner>
+  <owner>abigailbklein@chromium.org</owner>
+  <owner>chrome-desktop-ui-sea@google.com</owner>
+  <description>
+    Recorded when the read anything side panel entry is unpinned via the pin
+    button in the side panel header.
+  </description>
+</action>
+
 <action name="SidePanel.ReadingList.AddCurrentPage">
   <owner>corising@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
@@ -32735,6 +32841,15 @@
   </description>
 </action>
 
+<action name="SidePanel.ReadingList.Pinned.BySidePanelHeaderButton">
+  <owner>corising@chromium.org</owner>
+  <owner>chrome-desktop-ui-sea@google.com</owner>
+  <description>
+    Recorded when the reading list side panel entry is pinned via the pin button
+    in the side panel header.
+  </description>
+</action>
+
 <action name="SidePanel.ReadingList.Shown">
   <owner>corising@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
@@ -32743,6 +32858,15 @@
   </description>
 </action>
 
+<action name="SidePanel.ReadingList.Unpinned.BySidePanelHeaderButton">
+  <owner>corising@chromium.org</owner>
+  <owner>chrome-desktop-ui-sea@google.com</owner>
+  <description>
+    Recorded when the reading list side panel entry is unpinned via the pin
+    button in the side panel header.
+  </description>
+</action>
+
 <action name="SidePanel.ShoppingInsights.Shown">
   <owner>zhiyuancai@chromium.org</owner>
   <owner>chrome-shopping@google.com</owner>
@@ -32774,6 +32898,15 @@
   </description>
 </action>
 
+<action name="SidePanel.UserNotes.Pinned.BySidePanelHeaderButton">
+  <owner>corising@chromium.org</owner>
+  <owner>chrome-desktop-ui-sea@google.com</owner>
+  <description>
+    Recorded when the user notes side panel entry is pinned via the pin button
+    in the side panel header.
+  </description>
+</action>
+
 <action name="SidePanel.UserNotes.Shown">
   <owner>corising@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
@@ -32782,6 +32915,15 @@
   </description>
 </action>
 
+<action name="SidePanel.UserNotes.Unpinned.BySidePanelHeaderButton">
+  <owner>corising@chromium.org</owner>
+  <owner>chrome-desktop-ui-sea@google.com</owner>
+  <description>
+    Recorded when the user notes side panel entry is unpinned via the pin button
+    in the side panel header.
+  </description>
+</action>
+
 <action name="Signin_Abort_Signin">
   <owner>mahmadi@chromium.org</owner>
   <description>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index d84eb8a..fa06c45 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -67,13 +67,6 @@
   <int value="17" label="kMissingMoreAbout">MoreAbout URL is missing.</int>
 </enum>
 
-<enum name="AcceptChEntries">
-  <int value="0" label="no entries"/>
-  <int value="1" label="only valid entries"/>
-  <int value="2" label="only invalid entries"/>
-  <int value="3" label="both valid and invalid entries"/>
-</enum>
-
 <enum name="AcceptCHFrameRestart">
   <int value="0" label="Frame present"/>
   <int value="1" label="Navigation restarted"/>
@@ -1379,12 +1372,6 @@
   <int value="8" label="Rejected Due to Currency Mismatch"/>
 </enum>
 
-<enum name="AddressFamily">
-  <int value="0" label="Unspecified"/>
-  <int value="1" label="IPv4"/>
-  <int value="2" label="IPv6"/>
-</enum>
-
 <enum name="AdsInterventionStatus">
   <int value="0" label="Expired"/>
   <int value="1" label="Would Block"/>
@@ -1427,17 +1414,6 @@
   <int value="3" label="Coarse and fine pointers"/>
 </enum>
 
-<enum name="AlpsDecoderError">
-  <int value="0" label="NoError"/>
-  <int value="1" label="FramingError"/>
-  <int value="2" label="ForbiddenFrame"/>
-  <int value="3" label="NotOnFrameBoundary"/>
-  <int value="4" label="SettingsWithAck"/>
-  <int value="5" label="AcceptChInvalidStream"/>
-  <int value="6" label="AcceptChWithFlags"/>
-  <int value="7" label="AcceptChMalformed"/>
-</enum>
-
 <enum name="AlsaSampleFormatType">
   <int value="-1" label="SND_PCM_FORMAT_UNKNOWN"/>
   <int value="0" label="SND_PCM_FORMAT_S8"/>
@@ -1493,26 +1469,6 @@
   <int value="52" label="SND_PCM_FORMAT_DSD_U32_BE"/>
 </enum>
 
-<enum name="AlternateProtocolUsage">
-  <int value="0" label="ALTERNATE_PROTOCOL_USAGE_NO_RACE"/>
-  <int value="1" label="ALTERNATE_PROTOCOL_USAGE_WON_RACE"/>
-  <int value="2" label="ALTERNATE_PROTOCOL_USAGE_MAIN_JOB_WON_RACE"/>
-  <int value="3" label="ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING"/>
-  <int value="4" label="ALTERNATE_PROTOCOL_USAGE_BROKEN"/>
-  <int value="5"
-      label="ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_WITHOUT_RACE"/>
-  <int value="6" label="ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_RACE"/>
-  <int value="7" label="ALTERNATE_PROTOCOL_USAGE_UNSPECIFIED_REASON"/>
-</enum>
-
-<enum name="AlternativeServiceType">
-  <int value="0" label="No alternative service"/>
-  <int value="1" label="QUIC, destination same as origin"/>
-  <int value="2" label="QUIC, destination different from origin"/>
-  <int value="3" label="Not QUIC, destination same as origin"/>
-  <int value="4" label="Not QUIC, destination different from origin"/>
-</enum>
-
 <enum name="AltTabMode">
   <int value="0" label="All Desks"/>
   <int value="1" label="Current Desk"/>
@@ -1769,16 +1725,6 @@
   <int value="327695" label="5.15"/>
 </enum>
 
-<enum name="AndroidLocationPermissionState">
-  <int value="0" label="NoAccess">No location permissions are granted.</int>
-  <int value="1" label="AccessCoarse">
-    Permission to access approximate location (ACCESS_COARSE_LOCATION).
-  </int>
-  <int value="2" label="AccessFine">
-    Permission to access precise location (ACCESS_FINE_LOCATION).
-  </int>
-</enum>
-
 <enum name="AndroidMultiWindowActivityType">
   <int value="0" label="Enter"/>
   <int value="1" label="Exit"/>
@@ -7932,14 +7878,6 @@
   <int value="4" label="Unknown"/>
 </enum>
 
-<enum name="BlueZResultOfAdvertisementMonitor">
-  <int value="0" label="Success"/>
-  <int value="1" label="Unknown Error"/>
-  <int value="2" label="Invalid Parameters"/>
-  <int value="3" label="No Resource"/>
-  <int value="4" label="Busy"/>
-</enum>
-
 <enum name="BlueZResultOfAdvertisementRegistration">
   <int value="1" label="Success"/>
   <int value="2" label="LE unsupported"/>
@@ -8027,11 +7965,6 @@
   <int value="3" label="LE with random address"/>
 </enum>
 
-<enum name="BodyConsumerBaseFetchCheckPoint">
-  <int value="0" label="BodyConsumerBase Constructor"/>
-  <int value="1" label="BodyConsumerBase::DidFetchDataLoadFailed"/>
-</enum>
-
 <enum name="BookmarkBarState">
   <int value="0" label="Bookmark bar hidden"/>
   <int value="1" label="Bookmark bar shown"/>
@@ -8172,11 +8105,6 @@
   <int value="1" label="Notification click (within last 5 seconds)"/>
 </enum>
 
-<enum name="BooleanBroken">
-  <int value="0" label="Not Broken"/>
-  <int value="1" label="Broken"/>
-</enum>
-
 <enum name="BooleanBrowserSwitch">
   <int value="0" label="Stay"/>
   <int value="1" label="Switch browser"/>
@@ -8222,11 +8150,6 @@
   <int value="1" label="Timed out"/>
 </enum>
 
-<enum name="BooleanCoalesced">
-  <int value="0" label="not coalesced"/>
-  <int value="1" label="coalesced"/>
-</enum>
-
 <enum name="BooleanCodePathUsage">
   <summary>The result if a code path is being used.</summary>
   <int value="0" label="Unused Code Path"/>
@@ -8238,11 +8161,6 @@
   <int value="1" label="Completed"/>
 </enum>
 
-<enum name="BooleanConfirmed">
-  <int value="0" label="Not Confirmed"/>
-  <int value="1" label="Confirmed"/>
-</enum>
-
 <enum name="BooleanConnected">
   <int value="0" label="Not Connected"/>
   <int value="1" label="Connected"/>
@@ -8364,11 +8282,6 @@
   <int value="1" label="Previously connected"/>
 </enum>
 
-<enum name="BooleanExceeded">
-  <int value="0" label="Not exceeded"/>
-  <int value="1" label="Exceeded"/>
-</enum>
-
 <enum name="BooleanExists">
   <int value="0" label="Does not exist"/>
   <int value="1" label="Exists"/>
@@ -8632,11 +8545,6 @@
   <int value="1" label="Headers match"/>
 </enum>
 
-<enum name="BooleanOutOfDate">
-  <int value="0" label="Up-to-date"/>
-  <int value="1" label="Out-of-date"/>
-</enum>
-
 <enum name="BooleanOverlap">
   <int value="0" label="No overlap"/>
   <int value="1" label="Overlapped"/>
@@ -8652,11 +8560,6 @@
   <int value="1" label="Supports overlays"/>
 </enum>
 
-<enum name="BooleanPathIsInformative">
-  <int value="0" label="Path contains nothing except possibly a slash"/>
-  <int value="1" label="Path contains text beyond just an opening slash"/>
-</enum>
-
 <enum name="BooleanPhotosOptedIn">
   <int value="0" label="Opted-in"/>
   <int value="1" label="Not opted-in"/>
@@ -8667,11 +8570,6 @@
   <int value="1" label="Pinned"/>
 </enum>
 
-<enum name="BooleanPreferred">
-  <int value="0" label="Not Preferred"/>
-  <int value="1" label="Preferred"/>
-</enum>
-
 <enum name="BooleanPresent">
   <int value="0" label="Not Present"/>
   <int value="1" label="Present"/>
@@ -8788,9 +8686,6 @@
 </enum>
 
 <enum name="BooleanShown">
-  <obsolete>
-    Removed as of 06/2022
-  </obsolete>
   <int value="0" label="Not Shown"/>
   <int value="1" label="Shown"/>
 </enum>
@@ -8855,11 +8750,6 @@
   <int value="1" label="Toggled on"/>
 </enum>
 
-<enum name="BooleanTooMany">
-  <int value="0" label="Correct"/>
-  <int value="1" label="Too many"/>
-</enum>
-
 <enum name="BooleanUnderlay">
   <int value="0" label="Overlay Mode"/>
   <int value="1" label="Underlay Mode"/>
@@ -9053,15 +8943,6 @@
   <int value="1" label="HTTP Error"/>
 </enum>
 
-<enum name="BrokenAlternateProtocolLocation">
-  <int value="0" label="HTTP_STREAM_FACTORY_JOB"/>
-  <int value="1" label="QUIC_STREAM_FACTORY"/>
-  <int value="2" label="HTTP_STREAM_FACTORY_JOB_ALT"/>
-  <int value="3" label="HTTP_STREAM_FACTORY_JOB_MAIN"/>
-  <int value="4" label="QUIC_HTTP_STREAM"/>
-  <int value="5" label="HTTP_NETWORK_TRANSACTION"/>
-</enum>
-
 <enum name="BrotliFilterDecodingStatus">
   <int value="0" label="In progress"/>
   <int value="1" label="Done"/>
@@ -10382,11 +10263,6 @@
   <int value="2" label="Failed to set shill properties"/>
 </enum>
 
-<enum name="CertificateChangeNotificationType">
-  <int value="0" label="Trust"/>
-  <int value="1" label="Client Cert"/>
-</enum>
-
 <enum name="CertificateErrorReportEvent">
   <int value="0" label="Submitted"/>
   <int value="1" label="Failed"/>
@@ -11782,56 +11658,6 @@
   <int value="27" label="Not Registered"/>
 </enum>
 
-<enum name="ConnectionInfo">
-  <summary>
-    Application protocol used for HTTP response as defined in
-    net::HttpResponseInfo::ConnectionInfo.
-  </summary>
-  <int value="0" label="unknown"/>
-  <int value="1" label="HTTP/1.1"/>
-  <int value="2" label="SPDY/2 (deprecated)"/>
-  <int value="3" label="SPDY/3 (deprecated)"/>
-  <int value="4" label="HTTP/2"/>
-  <int value="5" label="QUIC (unknown version)"/>
-  <int value="6" label="HTTP/2 draft-14 (deprecated)"/>
-  <int value="7" label="HTTP/2 draft-15 (deprecated)"/>
-  <int value="8" label="HTTP/0.9"/>
-  <int value="9" label="HTTP/1.0"/>
-  <int value="10" label="QUIC/32"/>
-  <int value="11" label="QUIC/33"/>
-  <int value="12" label="QUIC/34"/>
-  <int value="13" label="QUIC/35"/>
-  <int value="14" label="QUIC/36"/>
-  <int value="15" label="QUIC/37"/>
-  <int value="16" label="QUIC/38"/>
-  <int value="17" label="QUIC/39"/>
-  <int value="18" label="QUIC/40"/>
-  <int value="19" label="QUIC/41"/>
-  <int value="20" label="QUIC/42"/>
-  <int value="21" label="QUIC/43"/>
-  <int value="22" label="HTTP/3 (Q099)"/>
-  <int value="23" label="QUIC/44"/>
-  <int value="24" label="QUIC/45"/>
-  <int value="25" label="QUIC/46"/>
-  <int value="26" label="QUIC/47"/>
-  <int value="27" label="QUIC/999"/>
-  <int value="28" label="HTTP/3 (Q048)"/>
-  <int value="29" label="HTTP/3 (Q049)"/>
-  <int value="30" label="HTTP/3 (Q050)"/>
-  <int value="31" label="HTTP/3 (T048)"/>
-  <int value="32" label="HTTP/3 (T049)"/>
-  <int value="33" label="HTTP/3 (T050)"/>
-  <int value="34" label="HTTP/3 (T099)"/>
-  <int value="35" label="HTTP/3 (draft-25)"/>
-  <int value="36" label="HTTP/3 (draft-27)"/>
-  <int value="37" label="HTTP/3 (draft-28)"/>
-  <int value="38" label="HTTP/3 (draft-29)"/>
-  <int value="39" label="HTTP/3 (T051)"/>
-  <int value="40" label="QUIC (RFC)"/>
-  <int value="41" label="QUICv2 draft-01 (deprecated)"/>
-  <int value="42" label="QUICv2 draft-08"/>
-</enum>
-
 <enum name="ConnectionResult">
   <int value="0" label="Success"/>
   <int value="1" label="Failure"/>
@@ -11985,14 +11811,6 @@
   <int value="74" label="SOFTBANK_ISO_2022_JP"/>
 </enum>
 
-<enum name="ContentEncodingType">
-  <int value="0" label="Unknown"/>
-  <int value="1" label="Brotli"/>
-  <int value="2" label="GZip"/>
-  <int value="3" label="Deflate"/>
-  <int value="4" label="Zstd"/>
-</enum>
-
 <enum name="ContentIndexCategory">
   <summary>
     The type of a Content Index entry. Corresponds to
@@ -13086,44 +12904,6 @@
   <int value="2" label="Corruption Detected After Mount"/>
 </enum>
 
-<enum name="CorsAccessCheckError">
-  <summary>
-    The detailed error type for CORS check failures. See
-    services/network/public/mojom/cors.mojom for detailed information.
-  </summary>
-  <int value="0" label="kDisallowedByMode"/>
-  <int value="1" label="kInvalidResponse"/>
-  <int value="2" label="kWildcardOriginNotAllowed"/>
-  <int value="3" label="kMissingAllowOriginHeader"/>
-  <int value="4" label="kMultipleAllowOriginValues"/>
-  <int value="5" label="kInvalidAllowOriginValue"/>
-  <int value="6" label="kAllowOriginMismatch"/>
-  <int value="7" label="kInvalidAllowCredentials"/>
-  <int value="8" label="kCorsDisabledScheme"/>
-  <int value="9" label="kPreflightInvalidStatus"/>
-  <int value="10" label="kPreflightDisallowedRedirect"/>
-  <int value="11" label="kPreflightWildcardOriginNotAllowed"/>
-  <int value="12" label="kPreflightMissingAllowOriginHeader"/>
-  <int value="13" label="kPreflightMultipleAllowOriginValues"/>
-  <int value="14" label="kPreflightInvalidAllowOriginValue"/>
-  <int value="15" label="kPreflightAllowOriginMismatch"/>
-  <int value="16" label="kPreflightInvalidAllowCredentials"/>
-  <int value="17" label="kPreflightMissingAllowPrivateNetwork"/>
-  <int value="18" label="kPreflightInvalidAllowPrivateNetwork"/>
-  <int value="19" label="kInvalidAllowMethodsPreflightResponse"/>
-  <int value="20" label="kInvalidAllowHeadersPreflightResponse"/>
-  <int value="21" label="kMethodDisallowedByPreflightResponse"/>
-  <int value="22" label="kHeaderDisallowedByPreflightResponse"/>
-  <int value="23" label="kRedirectContainsCredentials"/>
-  <int value="24" label="kInsecurePrivateNetwork"/>
-  <int value="25" label="kInvalidPrivateNetworkAccess"/>
-  <int value="26" label="kUnexpectedPrivateNetworkAccess"/>
-  <int value="27" label="kPreflightMissingPrivateNetworkAccessId"/>
-  <int value="28" label="kPreflightMissingPrivateNetworkAccessName"/>
-  <int value="29" label="kPrivateNetworkAccessPermissionUnavailable"/>
-  <int value="30" label="kPrivateNetworkAccessPermissionDenied"/>
-</enum>
-
 <enum name="CpuAbiBitnessSupport">
   <int value="0" label="Neither"/>
   <int value="1" label="32-bit only"/>
@@ -19572,83 +19352,6 @@
   <int value="3" label="Failed because Update Engine is busy"/>
 </enum>
 
-<enum name="DNS.AttemptType">
-  <int value="0" label="DnsUDPAttempt"/>
-  <int value="1" label="DnsTCPAttempt due to low UDP entropy"/>
-  <int value="2" label="DnsTCPAttempt due to retry due to UDP trucation"/>
-  <int value="3" label="DnsHTTPAttempt"/>
-</enum>
-
-<enum name="DNS.SvcbHttpsTransactionError">
-  <int value="0" label="No transaction error"/>
-  <int value="1" label="Insecure DNS transaction error (never task-fatal)"/>
-  <int value="2" label="Non-task-fatal Secure DNS transaction error"/>
-  <int value="3"
-      label="Would be task-fatal transaction error but finch param disabled"/>
-  <int value="4" label="Task-fatal transaction error"/>
-</enum>
-
-<enum name="DNS.TaskTypeMetadataAvailability">
-  <int value="0" label="SYSTEM, no metadata"/>
-  <int value="1" label="SYSTEM, with metadata"/>
-  <int value="2" label="DNS, no metadata"/>
-  <int value="3" label="DNS, with metadata"/>
-  <int value="4" label="SECURE_DNS, no metadata"/>
-  <int value="5" label="SECURE_DNS, with metadata"/>
-  <int value="6" label="MDNS, no metadata"/>
-  <int value="7" label="MDNS, with metadata"/>
-  <int value="8" label="CACHE_LOOKUP, no metadata"/>
-  <int value="9" label="CACHE_LOOKUP, with metadata"/>
-  <int value="10" label="INSECURE_CACHE_LOOKUP, no metadata"/>
-  <int value="11" label="INSECURE_CACHE_LOOKUP, with metadata"/>
-  <int value="12" label="SECURE_CACHE_LOOKUP, no metadata"/>
-  <int value="13" label="SECURE_CACHE_LOOKUP, with metadata"/>
-  <int value="14" label="CONFIG_PRESET, no metadata"/>
-  <int value="15" label="CONFIG_PRESET, with metadata"/>
-  <int value="16" label="NAT64, no metadata"/>
-  <int value="17" label="NAT64, with metadata"/>
-  <int value="18" label="HOSTS, no metadata"/>
-  <int value="19" label="HOSTS, with metadata"/>
-</enum>
-
-<enum name="DNS.UdpLowEntropyReason">
-  <int value="0" label="Multiple recent reassignments of the same UDP port"/>
-  <int value="1"
-      label="DNS query/response ID mismatches, where response ID is
-             recognized from a recent query"/>
-  <int value="2"
-      label="DNS query/response ID mismatches, where response ID is
-             unrecognized"/>
-  <int value="3" label="Exhaustion of process-wide UDP socket limit"/>
-</enum>
-
-<enum name="DNS.WindowsCompatibility">
-  <int value="0" label="Compatible"/>
-  <int value="1" label="Incompatible resolution policy"/>
-  <int value="2" label="Incompatible proxy"/>
-  <int value="3" label="Incompatible resolution policy and proxy"/>
-  <int value="4" label="Incompatible VPN"/>
-  <int value="5" label="Incompatible resolution policy and VPN"/>
-  <int value="6" label="Incompatible proxy and VPN"/>
-  <int value="7" label="Incompatible resolution policy, proxy and VPN"/>
-  <int value="8" label="Incompatible adapter specific nameserver"/>
-  <int value="9"
-      label="Incompatible resolution policy and adapter specific nameserver"/>
-  <int value="10" label="Incompatible proxy and adapter specific nameserver"/>
-  <int value="11"
-      label="Incompatible resolution policy, proxy and adapter specific
-             nameserver"/>
-  <int value="12" label="Incompatible VPN and adapter specific nameserver"/>
-  <int value="13"
-      label="Incompatible resolution policy, VPN and adapter specific
-             nameserver"/>
-  <int value="14"
-      label="Incompatible proxy, VPN and adapter specific nameserver"/>
-  <int value="15"
-      label="Incompatible resolution policy, proxy, VPN and adapter specific
-             nameserver"/>
-</enum>
-
 <enum name="DnsProxy.DnsOverHttpsMode">
   <int value="0" label="Unknown"/>
   <int value="1" label="Off"/>
@@ -19887,22 +19590,6 @@
   <int value="108" label="EpsonDs"/>
 </enum>
 
-<enum name="DohServerAutoupgradeStatus">
-  <int value="0" label="SuccessWithNoPriorFailures"/>
-  <int value="1" label="SuccessWithSomePriorFailures"/>
-  <int value="2" label="FailureWithSomePriorSuccesses"/>
-  <int value="3" label="FailureWithNoPriorSuccesses"/>
-</enum>
-
-<enum name="DomainReliabilityBeaconOutcome">
-  <int value="0" label="Unknown (should not be recorded)"/>
-  <int value="1" label="Uploaded successfully"/>
-  <int value="2" label="Expired"/>
-  <int value="3" label="Evicted"/>
-  <int value="4" label="Browsing data cleared"/>
-  <int value="5" label="Deleted at shutdown"/>
-</enum>
-
 <enum name="DownEventInputFormFactorDestinationCombination2">
   <int value="0"
       label="Unknown input in clamshell mode, destination is non-application
@@ -21153,16 +20840,6 @@
   <int value="6" label="Lock screen enabled, trust agent enabled"/>
 </enum>
 
-<enum name="ECDHECurves">
-  <int value="21" label="P-224"/>
-  <int value="23" label="P-256"/>
-  <int value="24" label="P-384"/>
-  <int value="25" label="P-521"/>
-  <int value="29" label="X25519"/>
-  <int value="16696" label="CECPQ2"/>
-  <int value="25497" label="Kyber+X25519"/>
-</enum>
-
 <enum name="EdidColorSpaceChecksOutcome">
   <int value="0" label="All checks passed"/>
   <int value="1" label="Bad primaries coordinates"/>
@@ -33908,11 +33585,6 @@
   </int>
 </enum>
 
-<enum name="FetchManagerLoaderCheckPoint">
-  <int value="0" label="FetchManager::Loader Constructor"/>
-  <int value="1" label="FetchManager::Loader::Failed"/>
-</enum>
-
 <enum name="FileDialogType">
   <int value="0" label="Select folder"/>
   <int value="1" label="Upload folder"/>
@@ -36201,79 +35873,6 @@
   <int value="2" label="NO_CONNECTION"/>
 </enum>
 
-<enum name="GeolocationAuthorizationAction">
-  <int value="0" label="Location authorized"/>
-  <int value="1" label="Location permanently denied (Don't Allow)"/>
-  <int value="2" label="Location denied at this prompt (Not Now)"/>
-</enum>
-
-<enum name="GeolocationHeaderPermissionState">
-  <int value="0" label="Location mode unknown"/>
-  <int value="1" label="High acc., app allowed, domain allowed, location sent"/>
-  <int value="2"
-      label="High acc., app allowed, domain allowed, location not sent"/>
-  <int value="3" label="High acc., app allowed, domain prompt, location sent"/>
-  <int value="4"
-      label="High acc., app allowed, domain prompt, location not sent"/>
-  <int value="5" label="High acc., app allowed, domain denied"/>
-  <int value="6" label="High acc., app prompt, domain allowed"/>
-  <int value="7" label="High acc., app prompt, domain prompt"/>
-  <int value="8" label="High acc., app prompt, domain denied"/>
-  <int value="9" label="High acc., app denied, domain allowed"/>
-  <int value="10" label="High acc., app denied, domain prompt"/>
-  <int value="11" label="High acc., app denied, domain denied"/>
-  <int value="12"
-      label="Battery sav., app allowed, domain allowed, location sent"/>
-  <int value="13"
-      label="Battery sav., app allowed, domain allowed, location not sent"/>
-  <int value="14"
-      label="Battery sav., app allowed, domain prompt, location sent"/>
-  <int value="15"
-      label="Battery sav., app allowed, domain prompt, location not sent"/>
-  <int value="16" label="Battery sav., app allowed, domain denied"/>
-  <int value="17" label="Battery sav., app prompt, domain allowed"/>
-  <int value="18" label="Battery sav., app prompt, domain prompt"/>
-  <int value="19" label="Battery sav., app prompt, domain denied"/>
-  <int value="20" label="Battery sav., app denied, domain allowed"/>
-  <int value="21" label="Battery sav., app denied, domain prompt"/>
-  <int value="22" label="Battery sav., app denied, domain denied"/>
-  <int value="23" label="GPS only, app allowed, domain allowed, location sent"/>
-  <int value="24"
-      label="GPS only, app allowed, domain allowed, location not sent"/>
-  <int value="25" label="GPS only, app allowed, domain prompt, location sent"/>
-  <int value="26"
-      label="GPS only, app allowed, domain prompt, location not sent"/>
-  <int value="27" label="GPS only, app allowed, domain denied"/>
-  <int value="28" label="GPS only, app prompt, domain allowed"/>
-  <int value="29" label="GPS only, app prompt, domain prompt"/>
-  <int value="30" label="GPS only, app prompt, domain denied"/>
-  <int value="31" label="GPS only, app denied, domain allowed"/>
-  <int value="32" label="GPS only, app denied, domain prompt"/>
-  <int value="33" label="GPS only, app denied, domain denied"/>
-  <int value="34" label="Location off, app allowed, domain allowed"/>
-  <int value="35" label="Location off, app allowed, domain prompt"/>
-  <int value="36" label="Location off, app allowed, domain denied"/>
-  <int value="37" label="Location off, app prompt, domain allowed"/>
-  <int value="38" label="Location off, app prompt, domain prompt"/>
-  <int value="39" label="Location off, app prompt, domain denied"/>
-  <int value="40" label="Location off, app denied, domain allowed"/>
-  <int value="41" label="Location off, app denied, domain prompt"/>
-  <int value="42" label="Location off, app denied, domain denied"/>
-  <int value="43" label="Unsuitable URL"/>
-  <int value="44" label="Not using HTTPS"/>
-</enum>
-
-<enum name="GeolocationHeaderSentOrNot">
-  <int value="0" label="Location disabled for Google domain"/>
-  <int value="1" label="Location preference not set for Google domain"/>
-  <int value="2" label="Location not available"/>
-  <int value="3" label="Location stale"/>
-  <int value="4" label="Header sent"/>
-  <int value="5" label="Location disabled for Chrome app"/>
-  <int value="6" label="iOS: Location disabled for Omnibox query"/>
-  <int value="7" label="Google domain does not accept locations"/>
-</enum>
-
 <enum name="GestureNavigationType">
   <int value="0" label="OS system Gesture navigation"/>
   <int value="1" label="Chrome custom Gesture navigation"/>
@@ -38389,95 +37988,6 @@
   <int value="1074610802" label="MF_I_MANUAL_PROXY"/>
 </enum>
 
-<enum name="Http2WireErrorCodes">
-  <summary>
-    Error codes defined at
-    https://www.iana.org/assignments/http2-parameters/http2-parameters.xhtml#error-code
-  </summary>
-  <int value="0" label="NO_ERROR"/>
-  <int value="1" label="PROTOCOL_ERROR"/>
-  <int value="2" label="INTERNAL_ERROR"/>
-  <int value="3" label="FLOW_CONTROL_ERROR"/>
-  <int value="4" label="SETTINGS_TIMEOUT"/>
-  <int value="5" label="STREAM_CLOSED"/>
-  <int value="6" label="FRAME_SIZE_ERROR"/>
-  <int value="7" label="REFUSED_STREAM"/>
-  <int value="8" label="CANCEL"/>
-  <int value="9" label="COMPRESSION_ERROR"/>
-  <int value="10" label="CONNECT_ERROR"/>
-  <int value="11" label="ENHANCE_YOUR_CALM"/>
-  <int value="12" label="INADEQUATE_SECURITY"/>
-  <int value="13" label="HTTP_1_1_REQUIRED"/>
-</enum>
-
-<enum name="HttpAuthCount">
-  <int value="0" label="Basic Start"/>
-  <int value="1" label="Basic Reject"/>
-  <int value="2" label="Digest Start"/>
-  <int value="3" label="Digest Reject"/>
-  <int value="4" label="NTLM Start"/>
-  <int value="5" label="NTLM Reject"/>
-  <int value="6" label="Negotiate Start"/>
-  <int value="7" label="Negotiate Reject"/>
-  <int value="8" label="SpdyProxy Start (Deprecated)"/>
-  <int value="9" label="SpdyProxy Reject (Deprecated)"/>
-</enum>
-
-<enum name="HttpAuthNtlmV2Usage">
-  <int value="0" label="Disabled over unsecured connection"/>
-  <int value="1" label="Disabled over secure connection"/>
-  <int value="2" label="Enabled over unsecured connection"/>
-  <int value="3" label="Enabled over secure connection"/>
-</enum>
-
-<enum name="HttpAuthPromptType">
-  <int value="0" label="Main frame with interstitial">
-    Auth prompt displayed over a blank interstitial
-  </int>
-  <int value="1" label="Main frame without interstitial">
-    Auth prompt displayed for the main frame, without a blank interstitial
-  </int>
-  <int value="2" label="Same origin subresource">
-    Auth prompt displayed for a subresource from the same origin
-  </int>
-  <int value="3" label="Cross origin subresource">
-    Auth prompt displayed for a subresource from a different origin
-  </int>
-</enum>
-
-<enum name="HttpAuthTarget">
-  <int value="0" label="Basic Proxy"/>
-  <int value="1" label="Basic Secure Proxy"/>
-  <int value="2" label="Basic Server"/>
-  <int value="3" label="Basic Secure Server"/>
-  <int value="4" label="Digest Proxy"/>
-  <int value="5" label="Digest Secure Proxy"/>
-  <int value="6" label="Digest Server"/>
-  <int value="7" label="Digest Secure Server"/>
-  <int value="8" label="NTLM Proxy"/>
-  <int value="9" label="NTLM Secure Proxy"/>
-  <int value="10" label="NTLM Server"/>
-  <int value="11" label="NTLM Secure Server"/>
-  <int value="12" label="Negotiate Proxy"/>
-  <int value="13" label="Negotiate Secure Proxy"/>
-  <int value="14" label="Negotiate Server"/>
-  <int value="15" label="Negotiate Secure Server"/>
-  <int value="16" label="SpdyProxy (Deprecated)"/>
-  <int value="17" label="SpdyProxy Secure (Deprecated)"/>
-  <int value="18" label="SpdyProxy Server (Invalid)"/>
-  <int value="19" label="SpdyProxy Secure Server (Invalid)"/>
-</enum>
-
-<enum name="HttpCachePattern">
-  <int value="0" label="Undefined"/>
-  <int value="1" label="Not Covered"/>
-  <int value="2" label="Not Cached"/>
-  <int value="3" label="Used"/>
-  <int value="4" label="Validated"/>
-  <int value="5" label="Updated"/>
-  <int value="6" label="CantConditionalize"/>
-</enum>
-
 <enum name="HttpMethods">
   <int value="0" label="UNKNOWN"/>
   <int value="1" label="GET"/>
@@ -38491,28 +38001,6 @@
   <int value="9" label="PATCH"/>
 </enum>
 
-<enum name="HttpNetworkTransactionRetryReason">
-  <int value="0" label="HttpRequestTimeout"/>
-  <int value="1" label="HttpMisdirectedRequest"/>
-  <int value="2" label="Http11Required"/>
-  <int value="3" label="SslClientAuthSignatureFailed"/>
-  <int value="4" label="ConnectionReset"/>
-  <int value="5" label="ConnectionClosed"/>
-  <int value="6" label="ConnectionAborted"/>
-  <int value="7" label="SocketNotConnected"/>
-  <int value="8" label="EmptyResponse"/>
-  <int value="9" label="EarlyDataRejected"/>
-  <int value="10" label="WrongVersionOnEarlyData"/>
-  <int value="11" label="Http2PingFailed"/>
-  <int value="12" label="Http2ServerRefusedStream"/>
-  <int value="13" label="Http2PushedStreamNotAvailable"/>
-  <int value="14" label="Http2ClaimedPushedStreamResetByServer"/>
-  <int value="15" label="Http2PushedResponseDoesNotMatch"/>
-  <int value="16" label="QuicHandshakeFailed"/>
-  <int value="17" label="QuicGoawayRequestCanBeRetried"/>
-  <int value="18" label="QuicProtocolError"/>
-</enum>
-
 <enum name="HttpResponseCode">
   <int value="100" label="100: Continue"/>
   <int value="101" label="101: Switching Protocols"/>
@@ -38600,27 +38088,6 @@
   </int>
 </enum>
 
-<enum name="HttpssvcDnsRcode">
-  <summary>
-    Tracks the result of querying for an INTEGRITY or HTTPSSVC record. This enum
-    can represent each of Chrome's supported RCODE values as well as any
-    unrecognized RCODE values. It also has the TimedOut value to represent
-    queries that timed out.
-
-    IANA registry:
-    https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml
-  </summary>
-  <int value="0" label="TimedOut"/>
-  <int value="1" label="UnrecognizedRcode"/>
-  <int value="2" label="MissingDnsResponse (network error)"/>
-  <int value="3" label="NOERROR"/>
-  <int value="4" label="FORMERR"/>
-  <int value="5" label="SERVFAIL"/>
-  <int value="6" label="NXDOMAIN"/>
-  <int value="7" label="NOTIMP"/>
-  <int value="8" label="REFUSED"/>
-</enum>
-
 <enum name="HwsecAttestationOpsStatus">
   <int value="0" label="kSuccess"/>
   <int value="1" label="kFailure (Deprecated)"/>
@@ -39612,13 +39079,6 @@
   <int value="118" label="TEST_THIRD_PARTY_COOKIE_PHASEOUT_DELEGATE"/>
 </enum>
 
-<enum name="InitialRttEstimateSource">
-  <int value="0" label="Default"/>
-  <int value="1" label="Cached"/>
-  <int value="2" label="2G"/>
-  <int value="3" label="3G"/>
-</enum>
-
 <enum name="InitialServiceWorkerStatus">
   <int value="0" label="kRunning"/>
   <int value="1" label="kStarting"/>
@@ -41539,15 +40999,6 @@
   </int>
 </enum>
 
-<enum name="JobProtocolErrorLocation">
-  <int value="0" label="kSessionStartReadingFailedAsync"/>
-  <int value="1" label="kSessionStartReadingFailedSync"/>
-  <int value="2" label="kCreateSessionFailedAsync"/>
-  <int value="3" label="kCreateSessionFailedSync"/>
-  <int value="4" label="CryptoConnectFailedSync"/>
-  <int value="5" label="CryptoConnectFailedAsync"/>
-</enum>
-
 <enum name="JpegColorSpace">
   <int value="0" label="Unknown color space">
     This is the bucket that counts the images that did not fall under any of the
@@ -51186,6 +50637,7 @@
   <int value="1197336536" label="printing-ppd-channel"/>
   <int value="1197363734" label="force-companion-pinned-state:disabled"/>
   <int value="1197439314" label="SwapBackquoteKeysInISOKeyboard:disabled"/>
+  <int value="1198011819" label="TimeOfDayWallpaperForcedAutoSchedule:enabled"/>
   <int value="1198019369" label="PlatformKeysAesEncryption:enabled"/>
   <int value="1198604672" label="DiscardExceptionsImprovements:disabled"/>
   <int value="1198839129" label="OfflinePagesLivePageSharing:enabled"/>
@@ -53197,6 +52649,8 @@
   <int value="2138431623" label="GlobalMediaControlsCrOSUpdatedUI:disabled"/>
   <int value="2138744939" label="ScreenSaverDuration:disabled"/>
   <int value="2139048614" label="UseSurfaceLayerForVideo:enabled"/>
+  <int value="2139164626"
+      label="TimeOfDayWallpaperForcedAutoSchedule:disabled"/>
   <int value="2139520082" label="EnableRestrictedWebApis:disabled"/>
   <int value="2140205372" label="ScreenAI"/>
   <int value="2140453427"
@@ -54670,11 +54124,6 @@
   <int value="11" label="kTest"/>
 </enum>
 
-<enum name="MediaResponseCacheType">
-  <int value="0" label="Transaction Cache Enabled"/>
-  <int value="1" label="Transaction Cache Disabled"/>
-</enum>
-
 <enum name="MediaSessionAction">
   <int value="0" label="Play"/>
   <int value="1" label="Pause"/>
@@ -55707,12 +55156,6 @@
   <int value="2" label="Multiple user profiles"/>
 </enum>
 
-<enum name="MultiPortStatusOnMigration">
-  <int value="0" label="Not validated"/>
-  <int value="1" label="Pending refresh validation"/>
-  <int value="2" label="Waiting for refresh validation"/>
-</enum>
-
 <enum name="MultiProfileSwitchActiveUserAction">
   <int value="0" label="System tray"/>
   <int value="1" label="Keyboard accelerator"/>
@@ -56432,17 +55875,6 @@
   <int value="3" label="Selected contacts"/>
 </enum>
 
-<enum name="NegotiatedHttpDatagramVersion">
-  <int value="0" label="Not supported"/>
-  <int value="1" label="draft-04"/>
-  <int value="2" label="rfc"/>
-</enum>
-
-<enum name="NegotiatedWebTransportVersion">
-  <int value="0" label="draft-02"/>
-  <int value="1" label="draft-07"/>
-</enum>
-
 <enum name="NeighborLinkMonitorFailureType">
   <int value="0" label="Unknown type of failure"/>
   <int value="1" label="IPv4 gateway neighbor lost"/>
@@ -56453,13 +55885,6 @@
   <int value="6" label="IPv6 gateway and DNS server neighbor lost"/>
 </enum>
 
-<enum name="NetCertificateNameNormalization">
-  <int value="0" label="Error parsing certificate chain"/>
-  <int value="1" label="Byte equal Names"/>
-  <int value="2" label="Normalized Names"/>
-  <int value="3" label="Chain contained only one certificate"/>
-</enum>
-
 <enum name="NetErrorCodes">
 <!-- Generated from net/base/net_error_list.h.
 Called by update_net_error_codes.py.-->
@@ -56736,187 +56161,6 @@
   <int value="1478" label="SSL_CLIENT_AUTH_NO_COMMON_ALGORITHMS_0"/>
 </enum>
 
-<enum name="NetErrorOfflineSuggestionType">
-  <int value="0" label="Prefetched Page">
-    A Prefetched article that has been offlined.
-  </int>
-  <int value="1" label="Video">
-    A video file previously downloaded by the user.
-  </int>
-  <int value="2" label="Audio">
-    An audio file previously downloaded by the user.
-  </int>
-  <int value="3" label="Other Page">
-    An offline page previously downloaded by the user.
-  </int>
-</enum>
-
-<enum name="NetErrorPageEvents">
-  <int value="0" label="Error Page Shown">
-    An error page was shown. This bucket encompasses all others and works as a
-    total count for error pages (instead of the histogram's total sample count
-    which doesn't reflect that information).
-  </int>
-  <int value="1" label="Reload Button Shown">
-    An error page was shown with at least a &quot;Reload&quot; button on it.
-  </int>
-  <int value="2" label="Reload Button Clicked">
-    An error page was shown with at least a &quot;Reload&quot; button on it and
-    the user pressed that button.
-  </int>
-  <int value="3" label="Reload Button Click Load Error">
-    An error page was previously loaded with a &quot;Reload&quot; button and
-    another load error happened as a result of the user pressing that button.
-  </int>
-  <int value="4" label="Show Saved Copy Button Shown">
-    An error page was shown with at least a &quot;Show Saved Copy&quot; button
-    on it.
-  </int>
-  <int value="5" label="Show Saved Copy Button Clicked">
-    An error page was shown with at least a &quot;Show Saved Copy&quot; button
-    on it and the user pressed that button.
-  </int>
-  <int value="6" label="Show Saved Copy Button Click Load Error">
-    An error page was previously loaded with a &quot;Show Saved Copy&quot;
-    button and another load error happened as a result of the user pressing that
-    button.
-  </int>
-  <int value="7" label="More Button Clicked">
-    An error page was shown with at least a &quot;More&quot; (aka
-    &quot;Details&quot;) button on it and the user pressed that button.
-  </int>
-  <int value="8" label="Browser Initiated Reload">
-    An error page was previously loaded and the user started a reload by
-    pressing the browser's reload button.
-  </int>
-  <int value="9" label="Both Reload And Show Saved Copy Buttons Shown">
-    An error page was shown with at least a &quot;Reload&quot; and a &quot;Show
-    Saved Copy&quot; buttons on it. Note that this is not exclusive with the
-    respective individual button buckets.
-  </int>
-  <int value="10"
-      label="Both Reload And Show Saved Copy Buttons Shown, Reload Clicked">
-    An error page was shown with at least a &quot;Reload&quot; and a &quot;Show
-    Saved Copy&quot; buttons on it and the user pressed the &quot;Reload&quot;
-    button. Note that this is not exclusive with the respective individual
-    button buckets.
-  </int>
-  <int value="11"
-      label="Both Reload And Show Saved Copy Buttons Shown, Show Saved Copy
-             Clicked">
-    An error page was shown with at least a &quot;Reload&quot; and a &quot;Show
-    Saved Copy&quot; buttons on it and the user pressed the &quot;Show Saved
-    Copy&quot; button. Note that this is not exclusive with the respective
-    individual button buckets.
-  </int>
-  <int value="12" label="Easter egg activated">
-    An error page was shown with the offline dino image and and the user
-    activated it (to play the dino game).
-  </int>
-  <int value="13" label="Show Cached Copy button shown">
-    An error page was shown with at least a &quot;Show Cached Copy&quot; button
-    on it.
-  </int>
-  <int value="14" label="Show Cached Copy button clicked">
-    An error page was shown with at least a &quot;Show Cached Copy&quot; button
-    on it and the user pressed that button.
-  </int>
-  <int value="15" label="Show Cached Page button shown">Obsolete.</int>
-  <int value="16" label="Show Cached Page button clicked">Obsolete.</int>
-  <int value="17" label="Diagnose button clicked">
-    An error page was shown with at least a &quot;Diagnose Error&quot; button on
-    it and the user pressed that button.
-  </int>
-  <int value="18" label="Show Offline Pages Button Shown">Obsolete.</int>
-  <int value="19" label="Show Offline Pages Button Clicked">Obsolete.</int>
-  <int value="20" label="Show Offline Copy Button Shown">Obsolete.</int>
-  <int value="21" label="Show Offline Copy Button Clicked">Obsolete.</int>
-  <int value="22" label="Download Button Shown">
-    An error page was shown with at least a &quot;Download Page Later&quot;
-    button on it.
-  </int>
-  <int value="23" label="Download Button Clicked">
-    An error page was shown with at least a &quot;Download Page Later&quot;
-    button on it and the user pressed that button.
-  </int>
-  <int value="24" label="Offline Suggestions List Shown">
-    A list containing at least one item of offline content suggestions was shown
-    in the expanded/shown state.
-  </int>
-  <int value="25" label="Offline Suggestion List Item Clicked">
-    An item from the offline content suggestions list was clicked.
-  </int>
-  <int value="26" label="Downloads Page Button Clicked">
-    A link that opens the downloads page was clicked.
-  </int>
-  <int value="27" label="Offline Content Summary Shown">
-    A summary of available offline content was shown.
-  </int>
-  <int value="28" label="Offline Suggestions List Shown Collapsed">
-    A list containing at least one item of offline content suggestions was shown
-    in the collapsed/hidden state.
-  </int>
-  <int value="29" label="Offline error shown">
-    The error page was shown because the device is offline (dino page).
-  </int>
-  <int value="30" label="Sign in to network button clicked">
-    An error page was shown with at least a &quot;Sign in to network&quot;
-    button on it and the user pressed that button.
-  </int>
-</enum>
-
-<enum name="NetFilterType2">
-  <summary>
-    Specific content decoding filter. See net::SourceStream::SourceType for more
-    details
-  </summary>
-  <int value="0" label="Brotli"/>
-  <int value="1" label="Deflate"/>
-  <int value="2" label="GZIP"/>
-  <int value="3" label="GZIPFallback"/>
-  <int value="4" label="SDCH"/>
-  <int value="5" label="SDCHPossible"/>
-  <int value="6" label="Invalid"/>
-  <int value="7" label="None"/>
-  <int value="8" label="Rejected">
-    Unlike other values, this one is reported from HttpNetworkTransaction in a
-    case when an unadvertised, but known encoding appears in a
-    &quot;Content-Encoding&quot; header, and is thus not comparable with the
-    other values, which are potentially returned from cached entries.
-  </int>
-  <int value="9" label="Unknown">
-    Reported from URLRequestHttpJob::SetUpSourceStream when an unknown encoding
-    appears in a &quot;Content-Encoding&quot; header. Despite being reported in
-    this histogram, this does not cause a CONTENT_DECODING_FAILED error.
-  </int>
-</enum>
-
-<enum name="NetNetworkErrorLoggingRequestOutcome">
-  <int value="0" label="Discarded: no NetworkErrorLoggingService"/>
-  <int value="1" label="Discarded: no ReportingService"/>
-  <int value="2" label="Discarded: insecure origin"/>
-  <int value="3" label="Discarded: no origin policy"/>
-  <int value="4" label="Discarded: unmapped error"/>
-  <int value="5" label="Discarded: Reporting upload"/>
-  <int value="6" label="Discarded: unsampled success"/>
-  <int value="7" label="Discarded: unsampled failure"/>
-  <int value="8" label="Queued"/>
-  <int value="9" label="Discarded: include_subdomains without DNS error"/>
-  <int value="10" label="Discarded: IP address mismatch"/>
-</enum>
-
-<enum name="NetReportingHeaderType">
-  <int value="0" label="Report-To"/>
-  <int value="1" label="Invalid Report-To"/>
-  <int value="2" label="Reporting-Endpoints"/>
-  <int value="3" label="Invalid Reporting-Endpoints"/>
-</enum>
-
-<enum name="NetReportingUploadHeaderType">
-  <int value="0" label="ReportTo"/>
-  <int value="1" label="ReportingEndpoints"/>
-</enum>
-
 <enum name="NetRequestPriority">
   <int value="0" label="Throttled"/>
   <int value="1" label="Idle"/>
@@ -56926,1097 +56170,6 @@
   <int value="5" label="Highest"/>
 </enum>
 
-<enum name="NetTrustAnchors">
-<!-- Generated from net/data/ssl/root_stores/root_stores.json.
-Called by update_net_trust_anchors.py.-->
-
-  <int value="0" label="Unknown or locally-installed trust anchor"/>
-  <int value="1"
-      label="1d75d0831b9e0885394d32c7a1bfdb3dbc1c28e2b0e8391fb135981dbc5ba936"/>
-  <int value="2"
-      label="4691cbfde84a6b6052ddbe152bb0c216ae25a86e5747813dbc0f147f338570be"/>
-  <int value="3"
-      label="c73afc2eba770d0cbc1ee41f252b52e8a93d12b72dccec031d8d839cbf818a79"/>
-  <int value="4"
-      label="a99972ce1f6c581d0097f62618062e53157b5276e1ec6651a3157057f057b339"/>
-  <int value="5"
-      label="628e3a1156f6faa92f94b409258d4cba3f2047480d30194faf3fbed05eaeb5b2"/>
-  <int value="6"
-      label="2b071c59a0a0ae76b0eadb2bad23bad4580b69c3601b630c2eaf0613afa83f92"/>
-  <int value="7"
-      label="8a27b5557b4bec7cc0305fbf3d53d1f71cd3f34910c5d65e27ecddb82077ba3d"/>
-  <int value="8"
-      label="cbe5ac15d88b5cac3f81e6df3bfb57bea60958813a47b77f3c5cb6b98191bdb5"/>
-  <int value="9"
-      label="e2d891efb738669105d530de5ed72e2b2ac3f4a67078b5349b3fdaca496f5eb8"/>
-  <int value="10"
-      label="563b3caf8cfef34c2335caf560a7a95906e8488462eb75ac59784830df9e5b2b"/>
-  <int value="11"
-      label="9dd55fc573f546cb6a3831d1112d8710a6f4f82dc87f5fae9d3a1a028dd36e4b"/>
-  <int value="12"
-      label="772fccca7d1646d60628134ff2e6e7f5ba095898be59698bce9d15f96f69a9f3"/>
-  <int value="13"
-      label="3c35e164bedd2cf12beb83ecff78b5e80da8158d2830217e4ebffce8928899a6"/>
-  <int value="14"
-      label="3b45918205c591298a1922a58b4921d01f648fa9d28bdddfad24aeec5942cfbf"/>
-  <int value="15"
-      label="a81293445db196a2030f9e455fe3c74a9a4f8317b02b01406027a8708174434c"/>
-  <int value="16"
-      label="eca0f181402ce7a8652b31b4d036df247e3a30b7f41a50d91ec4f90b006b43a1"/>
-  <int value="17"
-      label="8d767764b3cbda08929d072a22a561f4dcdd1bc57d3cbddc948c47d2b47f9122"/>
-  <int value="18"
-      label="706bb1017c855c59169bad5c1781cf597f12d2cad2f63d1a4aa37493800ffb80"/>
-  <int value="19"
-      label="ced43902ab5fb57b442322dc0e172a4fb55f7178b808f94e780a6fd6cc6bd818"/>
-  <int value="20"
-      label="6bcfc86c8ddc2af2e6a1180a2ddabb37b7ea3755316b64b9b8951bf0ca351f06"/>
-  <int value="21"
-      label="5632d97bfa775bf3c99ddea52fc2553410864016729c52dd6524c8a9c3b4489f"/>
-  <int value="22"
-      label="15f14ac45c9c7da233d3479164e8137fe35ee0f38ae858183f08410ea82ac4b4"/>
-  <int value="23"
-      label="bcfb44aab9ad021015706b4121ea761c81c9e88967590f6f94ae744dc88b78fb"/>
-  <int value="24"
-      label="acf65e1d62cb58a2bafd6ffab40fb88699c47397cf5cb483d42d69cad34cd48b"/>
-  <int value="25"
-      label="b03d87b056d08cc9d4e675ef19ca83ab53532168a8258598be72e6d85c7dd7c1"/>
-  <int value="26"
-      label="c3bc6100f57e320d8659f22584677e56860aab1014e0084a496fff8c880b6ba3"/>
-  <int value="27"
-      label="32d180ed31c935589ec9dbbb722123b883b5fc2dc10f9fca3a95d77e1bfcb534"/>
-  <int value="28"
-      label="fcf7da983603e88862030d96137d8e13031badfb4d56c1fd4cacc339f6bdbb2a"/>
-  <int value="29"
-      label="e42f24bd4d37f4aa2e56b979d83d1e65219fe0e9e3a382a1b3cb66c93955de75"/>
-  <int value="30"
-      label="7e8782c150ce3952f802e636023a5d3e95bb5d68e33e85adb2ba178125cebf15"/>
-  <int value="31"
-      label="aff988906dde12955d9bebbf928fdcc31cce328d5b9384f21c8941ca26e20391"/>
-  <int value="32"
-      label="ce24eb0626defd8168c96a7701f09301600fe5dd0dbce58e9c97b830af02ef28"/>
-  <int value="33"
-      label="63d9af9b47b1064d49a10e7b7fd566dbc8caa399459bfc2829c571ad8c6ef34a"/>
-  <int value="34"
-      label="942a6916a6e4ae527711c5450247a2a74fb8e156a8254ca66e739a11493bb445"/>
-  <int value="35"
-      label="40fcfc28875dccbfebcbdf6cd7433312da63c4efcf3bd7b1b505c22020ae0274"/>
-  <int value="36"
-      label="05570ae6eb0fceb4210e6db79486b7094caf200401e149b6677441b5f25e449b"/>
-  <int value="37"
-      label="05e77ef1fdfe05e2dca522cae64d8379a041b7b4f16c7cae36067a7f72a14872"/>
-  <int value="38"
-      label="1ea3c5e43ed66c2da2983a42a4a79b1e906786ce9f1b58621419a00463a87d38"/>
-  <int value="39"
-      label="1a7a3a1a68dd2361e3f3bb855f3b26fcd88b197d8dd4de06cf1b362ac89ec13b"/>
-  <int value="40"
-      label="15e7e717b428feee3af3afd9150dbad497008d3a3ff016964719907bdb01a645"/>
-  <int value="41"
-      label="cb6e91711ad6d55c8906f379cb071fb5c47933654a7415612eee6629f26fbcd7"/>
-  <int value="42"
-      label="76ee8590374c715437bbca6bba6028eadde2dc6dbbb8c3f610e851f11d1ab7f5"/>
-  <int value="43"
-      label="c746127c5f6b529ce9e2948efd9465444089319acf03f34d0bf37eadc77db22f"/>
-  <int value="44"
-      label="952c2039c0243eb515dd73d83fc3643184874feb0862a9837731ed9b4742e17a"/>
-  <int value="45"
-      label="1069fa47a0aa4f8cf7111b1caea365eeaed10bfff32660def6e0614bfae70875"/>
-  <int value="46"
-      label="d1de2ae61c8df2fa623966163d4c73d460bfc428e57585be6bfeb9a56323d1b6"/>
-  <int value="47"
-      label="4002fcd311d07331567e71bcd971e46048c8dce8d1659711753b3daa2a269afa"/>
-  <int value="48"
-      label="b2def5362ad3facd04bd29047a43844f767034ea4892f80e56bee690243e2502"/>
-  <int value="49"
-      label="9318226f8c83afe47f5f47c24f59ce12dba8c73b181bee6b2ea1f40a06bc1869"/>
-  <int value="50"
-      label="967b0cd93fcef7f27ce2c245767ae9b05a776b0649f9965b6290968469686872"/>
-  <int value="51"
-      label="44af8afcf1395d2a8e30ef812ce19ceb2e8948dfd21e00fbaa34689f9a24721f"/>
-  <int value="52"
-      label="17755a5c295f3d2d72e6f031a1f07f400c588b9e582b22f17eae31a1590d1185"/>
-  <int value="53"
-      label="86c13a3408dd1aa77ee8b6947c03958772f531248c1627befb2c4f4b04d04496"/>
-  <int value="54"
-      label="ff5680cd73a5703da04817a075fd462506a73506c4b81a1583ef549478d26476"/>
-  <int value="55"
-      label="006d7be7555dd82026442c4f1a27a80e89a1989cb87b34448ed2194c18196d5e"/>
-  <int value="56"
-      label="43cffc359f2e8caa57388ee9f6f1dbe93bf093682a699ac3852e6d1f8579e7f9"/>
-  <int value="57"
-      label="be3db7b79bfe579dcf9b07ca4cad75aff16975568e5b45cfcae4d61fb63175a8"/>
-  <int value="58"
-      label="5192438ec369d7ee0ce71f5c6db75f941efbf72e58441715e99eab04c2c8acee"/>
-  <int value="59"
-      label="25d4913cf587097414d29d26f6c1b1942cd6d64eaf45d0fcf81526adba96d324"/>
-  <int value="60"
-      label="f48badd7df6a06690d0ae31373b12855f8dedb14517f362a313101cc98cc6b35"/>
-  <int value="61"
-      label="25aeec63f3ccd73dd61cb4fbbd13603722e02cb54e03047737084211071d7850"/>
-  <int value="62"
-      label="10ba3485ca8bb6880ab9531a4063e4001555561c7f2e055165f49b2d74fc5f6b"/>
-  <int value="63"
-      label="1906c6124dbb438578d00e066d5054c6c37f0fa6028c05545e0994eddaec8629"/>
-  <int value="64"
-      label="23f2edff3ede90259a9e30f40af8f912a5e5b3694e6938440341f6060e014ffa"/>
-  <int value="65"
-      label="9adb99c93ab256ecca2b5350c75048a8584c12dfc248e3f60ea9354c34ebfcce"/>
-  <int value="66"
-      label="9736ac3b25d16c45a45418a964578156480a8cc434541ddc5dd59233229868de"/>
-  <int value="67"
-      label="a6e11ff15ec326a5e3f18ad33a056694dc84c699766d028a5ad0efe1a8e53ac7"/>
-  <int value="68"
-      label="b638cff05c8a832758edc3028af9e2d55514568bc6bb34ab36d140b97ac6b12d"/>
-  <int value="69"
-      label="023c81cce8e7c64fa942d3c15048707d35d9bb5b87f4f544c5bf1bc5643af2fa"/>
-  <int value="70"
-      label="a6f1f9bf8a0a9ddc080fb49b1efc3d1a1c2c32dc0e136a5b00c97316f2a3dc11"/>
-  <int value="71"
-      label="bd153ed7b0434f6886b17bce8bbe84ed340c7132d702a8f4fa318f756ecbd6f3"/>
-  <int value="72"
-      label="b1124142a5a1a5a28819c735340eff8c9e2f8168fee3ba187f253bc1a392d7e2"/>
-  <int value="73"
-      label="051cf9fa95e40e9b83edaeda6961f6168c7879c4660172479cdd51ab03cea62b"/>
-  <int value="74"
-      label="36ecc61fc7e5f1923d167e67dfde34608549b34a63c7c6e60ffd5c1840381f5c"/>
-  <int value="75"
-      label="87af34d66fb3f2fdf36e09111e9aba2f6f44b207f3863f3d0b54b25023909aa5"/>
-  <int value="76"
-      label="9392ae2149924ade37e645dba1ff4bdddcda2b291b6097669d2afa5c7a372619"/>
-  <int value="77"
-      label="8fd112c3c8370f147d5ccd3a7d865eb8dd540783bac69fc60088e3743ff33378"/>
-  <int value="78"
-      label="0656f5955204c8d2bc8b1ca475e2a4fa6e124d124512784157c858b55471141a"/>
-  <int value="79"
-      label="495a96ba6bad782407bd521a00bace657bb355555e4bb7f8146c71bba57e7ace"/>
-  <int value="80"
-      label="5a889647220e54d6bd8a16817224520bb5c78e58984bd570506388b9de0f075f"/>
-  <int value="81"
-      label="5955ae291574a931342cf7450e16652ede1e0fb3097e1571dfac11c915601564"/>
-  <int value="82"
-      label="b4a039eafc4310ba9bde093edb8f9d9d0b3d4c7c004d48288c35dbcc19467d18"/>
-  <int value="83"
-      label="2a29337c3d6224cc53f0bb5e5d5820c0d8848b04871328f090fee3cd6bf821b4"/>
-  <int value="84"
-      label="808d68b3fab4884a5f971ace7d10550d7a95a163774f3ec36afffb213fbe4c74"/>
-  <int value="85"
-      label="94072ad3f58f70f93098e5a5f6c04c96c710bd849d83184919ae90eb890ae400"/>
-  <int value="86"
-      label="7caa03465124590c601e567e52148e952c0cffe89000530fe0d95b6d50eaae41"/>
-  <int value="87"
-      label="dbc1e3a15238a0483bcdb8fdec616e03e705a48e2a501157cadf3b9c7311c5e5"/>
-  <int value="88"
-      label="1f4224cec84fc99ced881ff6fcfd3e21f8c519c547aa6a5dd3de247302ce50d1"/>
-  <int value="89"
-      label="e7ca91bbfbb18788057b3a8070446ea5291160194102f7dcc3b9848c63cb9cd5"/>
-  <int value="90"
-      label="56174d3ad971a8944964b189811f3008493a6a90422e3c5804ec838d4f94f622"/>
-  <int value="91"
-      label="0c7acaa710226720bbc940349ee2e6148652a89dbf406a232c895f6dc78ebb9a"/>
-  <int value="92"
-      label="702116ccd8bf23e16466f0e0dba0ed6a239a9c1cd6a8f5a66b39af3595020385"/>
-  <int value="93"
-      label="aa2630a7b617b04d0a294bab7a8caaa5016e6dbe604837a83a85719fab667eb5"/>
-  <int value="94"
-      label="36c22314131a5fbf1b70ea4ccf4bc13a777d938ec65e1da24e3c2cfd01d3d163"/>
-  <int value="95"
-      label="4905466623ab4178be92ac5cbd6584f7a1e17f27652d5a85af89504ea239aaaa"/>
-  <int value="96"
-      label="f463c54d9f1a047aed52656ac785e07ebec528e0207bfd3f55d893237668f6ae"/>
-  <int value="97"
-      label="62554c17005543b237215f04268dcd2fd1c470240ad3c8660e25ae2c59630f55"/>
-  <int value="98"
-      label="6544ff9adb642c4c3698a60d8143b6b93bcef01365b540f614dcc2a45ab94d31"/>
-  <int value="99"
-      label="927a1b8562280576d048c50321ada43d8703d2d9521a18c28b8c46cc6aae4efd"/>
-  <int value="100"
-      label="4eada9b5311e718199d98ea82b95005cba93198ab1f97efcbe8dc6201628f8af"/>
-  <int value="101"
-      label="3861d7b6961fcdb2120456ff6fc2eb7704b1a741b4bd933a8376f5e1915ca698"/>
-  <int value="102"
-      label="2a4212605aa3e8aecb0fc19806cf3b40b53b95f1a34dbbd6e3ed27230324abb3"/>
-  <int value="103"
-      label="d2a5f32f0e01b910ef4e3b46bf84e5af5fb5689e7d1507e929e368ac88c6cc76"/>
-  <int value="104"
-      label="67dc4f32fa10e7d01a79a073aa0c9e0212ec2ffc3d779e0aa7f9c0f0e1c2c893"/>
-  <int value="105"
-      label="bb4128ec9620f2d2a49ce8e2c4e257aebad93a0f11c56b5fa4b00e23759fa39d"/>
-  <int value="106"
-      label="a4003bd5bdd894e01a8e01e06b62c7aa82f03de5253133570aad4fd0e7d81d3c"/>
-  <int value="107"
-      label="b21d2a743318712ba16f39919d961a4bafba3bca9a43a75b1fcfe22c5d70caba"/>
-  <int value="108"
-      label="c444b5b66ce5d71e1b5e40f27385c95cbfd24a05b56f70cac0992f0f50c3379c"/>
-  <int value="109"
-      label="2bcee858158cf5465fc9d76f0dfa312fef25a4dca8501da9b46b67d1fbfa1b64"/>
-  <int value="110"
-      label="fea2b7d645fba73d753c1ec9a7870c40e1f7b0c561e927b985bf711866e36f22"/>
-  <int value="111"
-      label="92c46879626ef2cc1ecea50c72fb5e385844095f21cbf3b283cb82e6b9fc6a58"/>
-  <int value="112"
-      label="e5ca37bc7b6c361979bc6b123ca9a1db019046d7ff5f57dfb854b19d10b0682f"/>
-  <int value="113"
-      label="2a8f2d8af0eb123898f74c866ac3fa669054e23c17bc7a95bd0234192dc635d0"/>
-  <int value="114"
-      label="093db767888f6b1327555dbd42bb5c93fedec5044c7a84bc6ea32a578c2235c0"/>
-  <int value="115"
-      label="23849d094923d44a4881b63ab185e9be15aac8ef2c3044d934bc7f26e2d2cd69"/>
-  <int value="116"
-      label="2596904dc4d699ae20c2cef4dce47f285937d77464ac370746f52dea76ba0c28"/>
-  <int value="117"
-      label="6dbfae00d37b9cd73f8fb47de65917af00e0dddf42dbceac20c17c0275ee2095"/>
-  <int value="118"
-      label="f53c22059817dd96f400651639d2f857e21070a59abed9079400d9f695506900"/>
-  <int value="119"
-      label="fac95de3c24a174194800cffaa3ca51d7116630664a9b60c8758b4ef0dc58f88"/>
-  <int value="120"
-      label="a87443b3d896eb257ccce99b95ada9bc81b9db4e3142aa9a99af0942cb0a4a3a"/>
-  <int value="121"
-      label="567b8211fd20d3d283ee0cd7ce0672cb9d99bc5b487a58c9d54ec67f77d4a8f5"/>
-  <int value="122"
-      label="ab98495276adf1ecaff28f35c53048781e5c1718dab9c8e67a504f4f6a51328f"/>
-  <int value="123"
-      label="fd872d176617e50c266119d0fdb047b0732da2048b121af7b9860ca3e2f2f2be"/>
-  <int value="124"
-      label="c1ad1b1898ec395048df070bfa217e25c913bed8ca6b73de085528846a0103c1"/>
-  <int value="125"
-      label="3219b09114ff495a3eb6eb00c2efeab34002ae5f0a56c7679ea087a3fa037e4f"/>
-  <int value="126"
-      label="67ea193243ae383939b5ad9e356a6b2bf93a93bcdcf828a47082497883083f86"/>
-  <int value="127"
-      label="77290717614b25f12964ebdb38b5f83caadc0f6c36b0777f880fc6dee1d339cc"/>
-  <int value="128"
-      label="3b0d73b4be4a854adc3e51d7ef9fa48aefbb2cdd824d67bdc7d7d09a2abc2d43"/>
-  <int value="129"
-      label="effee1f1e5f39f42ff80d471c9c5a799a8c843f9b676315f9eab3f4c7a2f7fc8"/>
-  <int value="130"
-      label="3380709af3b096be3cc2a40548142c0a520028db09e2cb77ae2206616ab6cbb4"/>
-  <int value="131"
-      label="4bdc636f48d21fb68c5a3cd4a20685788043bdb524e7e84d4192c451ee3429b5"/>
-  <int value="132"
-      label="d0773adb60043e954309d9714fe053eaad8aa5b9586edba468e276df82065adf"/>
-  <int value="133"
-      label="ff342fb6c4c8bd30a4706f73489539f19e6e48cc05f46254654f6610dbc540e9"/>
-  <int value="134"
-      label="c7f43b4cf5b71568294f822b53762605f6ddd15cadece739e9e2c3cba61e9d67"/>
-  <int value="135"
-      label="9c6f6a123cbaa4ee34dbeceee24c97d738878cb423f3c2273903424f5d1f6dd5"/>
-  <int value="136"
-      label="052b687107ec84e8730382452ec2a27451745d7485a57d6f464e0da7a1b6af2a"/>
-  <int value="137"
-      label="6c464b9a5b233a5e874da765c26f045010d2ddcff45794f0b4c7e4aafa501495"/>
-  <int value="138"
-      label="3499f93fd394523bfb1ec4c3ad4dfb310131fbe9ee5476bde6295de808d5dd8f"/>
-  <int value="139"
-      label="9699225c5de52e56cdd32df2e96d1cfea5aa3ca0bb52cd8933c23b5c27443820"/>
-  <int value="140"
-      label="26c18dc6eea6f632f676bceba1d8c2b48352f29c2d5fcda878e09dcb832dd6e5"/>
-  <int value="141"
-      label="616167201433aea6c8e5e3070afcaf6749188f814bd1abb179ae8dad3abf26ec"/>
-  <int value="142"
-      label="b0f6f15b4817ebe6fe0b4bfcd7d3ace4c758b0ab6f8a9da2ed92e618239d9c98"/>
-  <int value="143"
-      label="3a803e7c0a43a29fd73672e3d0bb2c3653d948ede0b3cb1db4ce75a857e89af1"/>
-  <int value="144"
-      label="9ecc51368e86e3460f66c295e4942dd53080f27b1e410aff2d1aa9d4e6bc7e7c"/>
-  <int value="145"
-      label="8a2affbd1a1c5d1bdccbb7f548ba995f966806b3fd0c3a00fae2e52f3c853989"/>
-  <int value="146"
-      label="1528397da212890a830b0b95a59968cef234773779df5181cf10fa647534bb65"/>
-  <int value="147"
-      label="31de0cb19f2adbb0d1cd7b1b31ef8ee3eb59b74459aef94b480beeeeb85c64c9"/>
-  <int value="148"
-      label="cf0b474ace8469faba402f02eebdf9e1700d9cbe8be4e4348407b69dd3196e94"/>
-  <int value="149"
-      label="980922eee07f86bc7f5e5e95d57db8bdae68e17a421c4e72a96a708a87920124"/>
-  <int value="150"
-      label="3551de58a7d79cd980283df81790d63a982c1a63b30482ec5821db7661554ef9"/>
-  <int value="151"
-      label="6f3e077fe5504646c0191afce494e4eb68183e398f5a4dc05669f8b6e6e682fe"/>
-  <int value="152"
-      label="25b41b506e4930952823a6eb9f1d31def645ea38a5c6c6a96d71957e384df058"/>
-  <int value="153"
-      label="d8fb33e385c9c2da729a84706ba927dcbb79273e122ffd9673363b70b7f36cbb"/>
-  <int value="154"
-      label="510d20e5c47f63cf666b20f61af62bc099a42ac824ffa443a2da7c90b1808a91"/>
-  <int value="155"
-      label="4d40e7af4304a09de87fbf9896204c055141e3f809b2fe733bb2310fdf98a162"/>
-  <int value="156"
-      label="4462c107c485dd6a5443f5e7a1604416034a374c3f4d10875f1c3715027563af"/>
-  <int value="157"
-      label="04a6ea654b23658973c98198c64a3a691c0da72ebebd9aebf75324cde6960eaa"/>
-  <int value="158"
-      label="fc3b82796b572ca9731993635db8cf07c2bf01e199b2f273a3f953bd185de3c0"/>
-  <int value="159"
-      label="5e7673a17a08d61413cd51b57dbaacbebfe5acb915e3966e5321b13eb9efaaeb"/>
-  <int value="160"
-      label="ab5cdb3356397356d6e691973c25b8618b65d76a90486ea7a8a5c17767f4673a"/>
-  <int value="161"
-      label="2a8bed32ae680d2d187b9a7afd171d83fd0b935eaf9e2c1b43e80278d2063e39"/>
-  <int value="162"
-      label="1916f3508ec3fad795f8dc4bd316f9c6085a64de3c4153ac6d62d5ea19515d39"/>
-  <int value="163"
-      label="278a6391d3d36b49aa4080f56a36b3c10fba4e28aa6a9592a82e7535113a12d3"/>
-  <int value="164"
-      label="5f665b4060be9efaf6ad739f6b39a1db9847277eb8dc144045376de1009e3127"/>
-  <int value="165"
-      label="16d82d67a1ed8e89f9ab58f7d0fd3eb0d0017687fcaeecd40475f10083a5b593"/>
-  <int value="166"
-      label="81a98fc788c35f557645a95224e50cd1dac8ffb209dc1e5688aa29205f132218"/>
-  <int value="167"
-      label="c07135f6b452398264a4776dbd0a6a307c60a36f967bd26321dcb817b5c0c481"/>
-  <int value="168"
-      label="db15c0062b520f318a19dacfecd64f9e7a3fbe609fd586796f20ae028e8e3058"/>
-  <int value="169"
-      label="4a49edbd2f8f8230bd5592b313573fe1c172a45fa98011cc1eddbb36ade3fce5"/>
-  <int value="170"
-      label="86a68f050034126a540d39db2c5f917ef66a94fb9619fa1ecd827cea46ba0cb0"/>
-  <int value="171"
-      label="f1c6ba670cfc88e4df52973cae420f0a089dd474144fe5806c420064e1591229"/>
-  <int value="172"
-      label="d6a18443d348db994f934ccd8e635d833a27ac1e56f8afaf7c97cb4f43eab68b"/>
-  <int value="173"
-      label="59df317bfa9f4f0ab7ca514d7772296aa2c765b87664d08b96e57399e364729c"/>
-  <int value="174"
-      label="15eed339594b304f8cf847b477371d8d6fec61f4db2b01af589e7c53b35cae4c"/>
-  <int value="175"
-      label="8bb593a93be1d0e8a822bb887c547890c3e706aad2dab76254f97fb36b82fc26"/>
-  <int value="176"
-      label="6106c0e3a0a299831875127bd7d3cc1859803d511cac11eb6e0840dd166fc10e"/>
-  <int value="177"
-      label="f3438e23b3ce532522facf307923f58fd18608e9ba7addc30e952b43c49616c3"/>
-  <int value="178"
-      label="b94c198300cec5c057ad0727b70bbe91816992256439a7b32f4598119dda9c97"/>
-  <int value="179"
-      label="2021917e98263945c859c43f1d73cb4139053c414fa03ca3bc7ee88614298f3b"/>
-  <int value="180"
-      label="08b3a6335fce5ef48f8f0e543986c07fd18a3b1226129f61864bbd5bdd1f1cc9"/>
-  <int value="181"
-      label="7e0ead76bb6819dc2f54511a84354f6e8b307b9dd82058ea6c004f01d9dda5df"/>
-  <int value="182"
-      label="c784333d20bcd742b9fdc3236f4e509b8937070e73067e254dd3bf9c45bf4dde"/>
-  <int value="183"
-      label="82b5f84daf47a59c7ab521e4982aefa40a53406a3aec26039efa6b2e0e7244c1"/>
-  <int value="184"
-      label="4b72dfed3edccb5f4945682e295731a0864ac6b5b85b193ecd2f06b4900c1cfd"/>
-  <int value="185"
-      label="951ee046fa83316e6786c08c44f13b4ca2ead2d2644d63314391c0cc70887d0d"/>
-  <int value="186"
-      label="58dd61feb36ea7d258724371709149cb121337864cacb2d0999ad20739d06477"/>
-  <int value="187"
-      label="4223894003a881c5df6bab163db235c221a18d54bf759945820e670da82e3f39"/>
-  <int value="188"
-      label="4a2659666dc0203b916f53d80ad8f61ac30bea161f485cc7527e6a5937e49216"/>
-  <int value="189"
-      label="dd5ed1c090f9f448061baa94a6bb11017544e9eefaa20cc714ce6c633f5dc629"/>
-  <int value="190"
-      label="07e854f26a7cbd389927aa041bfef1b6cd21dd143818ad947dc655a9e587fe88"/>
-  <int value="191"
-      label="6b1a505e0246f2f60c490ff0c097a7be27210cbb7500237f88b0cd48298bc9b8"/>
-  <int value="192"
-      label="381a3fc7a8b082fa28613a4d07f2c7553f4e1918ee07caa9e8b7cede5a9ca06a"/>
-  <int value="193"
-      label="6e364b6133deefdcbb21273c5f445a20afbc05038d5b021c0c2153039016345b"/>
-  <int value="194"
-      label="6b3b57e9ec88d1bb3d01637ff33c7698b3c9758255e9f01ea9178f3e7f3b2b52"/>
-  <int value="195"
-      label="7aedddf36b18f8acb7379fe1ce183212b2350d0788abe0e82457be9badad6d54"/>
-  <int value="196"
-      label="149f2ee63b9a5e5803240a770dc991fc2e3445e62831c245a49bc4f1f738ff9c"/>
-  <int value="197"
-      label="ec9056fe9509411609763aee831ef37c832b75b3d727528fc7c75201c1ff28e6"/>
-  <int value="198"
-      label="675605f1567e25fbd2526befea2aefbdb2279f3e1baa3a303ae7555d1bda3ee4"/>
-  <int value="199"
-      label="891ff898e4a8d555140056e3176eea91f4d808ee7f6d1bfbcce6f84807639f91"/>
-  <int value="200"
-      label="0b9fa5a59eed715c26c1020c711b4f6ec42d58b0015e14337a39dad301c5afc3"/>
-  <int value="201"
-      label="bb52086d0639e8db332775ac8f4e8435d92ceb00f4e24f28fc0eabe240772e80"/>
-  <int value="202"
-      label="6d6f0c340971a218a31d10330ea9ae7c7a6550534c6eefeddd2118e114db473e"/>
-  <int value="203"
-      label="5375662628fa0a6840aec8c592bf5d8de564ed3efb62c7c932fca8d754d9bbd6"/>
-  <int value="204"
-      label="50cc86ba96db3263c79a43ead07553d9f56659e6907e72d8c026637a1cdc85dc"/>
-  <int value="205"
-      label="36abc32656acfc645c61b71613c4bf21c787f5cabbee48348d58597803d7abc9"/>
-  <int value="206"
-      label="2fc5667a4b9a2678ed6ac6ad25465fcbf6094bfcd9504097c7a8fa47ade5e888"/>
-  <int value="207"
-      label="b738290cc08547e79ac67f831ebb33547c4e7db4514e2d2988c23c441340eb41"/>
-  <int value="208"
-      label="f7ecded5c66047d28ed6466b543c40e0743abe81d109254dcf845d4c2c7853c5"/>
-  <int value="209"
-      label="7f4296fc5b6a4e3b35d3c369623e364ab1af381d8fa7121533c9d6c633ea2461"/>
-  <int value="210"
-      label="fbe3018031f9586bcbf41727e417b7d1c45c2f47f93be372a17b96b50757d5a2"/>
-  <int value="211"
-      label="b1be0f7a5e638b559d8b521fef6017ad8fa16eb0548e846b2ac4b41d89b41f14"/>
-  <int value="212"
-      label="e43dea894f42cecf4a1dd60ed1dab82f7c0a308ae32a3d49a7aa1a3e957015f7"/>
-  <int value="213"
-      label="c5697be91cd655539b560758e91b6e085461623741034c485e47d7e9d25a03c0"/>
-  <int value="214"
-      label="80dbfb97bdd3926baee41f73c5588faa17d707b03adf4907a2bc677f3ef1717c"/>
-  <int value="215"
-      label="eb4993efa9b089e593418aa893f8e93a7374d810e52fcbe01e7f1d7e92a6d024"/>
-  <int value="216"
-      label="674039e472561963c8cb00d21a97a90a18bb8a1c4c317ac67e382a652bb573c0"/>
-  <int value="217"
-      label="9b219d0fbff36a5fb32090571906bceea68617c833a3f61b81e962a8e64db8af"/>
-  <int value="218"
-      label="da8796be34cc81abee7304c4d2bca0ac984c5b24b61b13e2285e1d27ad8cebf0"/>
-  <int value="219"
-      label="ede4b1535a529bf1606bc6ff757b91470aa30aeaffd2d6df2eba340dae302fca"/>
-  <int value="220"
-      label="a7a8f039894f5f675e92a778e008e424c9417dba06a1738b45b4e08d36fc2d7c"/>
-  <int value="221"
-      label="659cb368ac56998bd07af2cafc5fb93f8e79474accc2a6cf1ac9f2192d136360"/>
-  <int value="222"
-      label="f8e5f905bc939911267b83d50814a90323b51e183629db52d4fc2d5468a5a578"/>
-  <int value="223"
-      label="98ca29f313386721afbf5d14f1abcaa1dc63cc8d1fd7dc361f6b01368938f24b"/>
-  <int value="224"
-      label="915086ccd4ed1ea749b427f6b0ceb4a0ef5b4a1cf18070539c0f2a758185a382"/>
-  <int value="225"
-      label="3fab784fc3c9ab9eedc12ecdc0db550f4c3dbfd3e86d78815333c5eba518cb9d"/>
-  <int value="226"
-      label="22076e5aef44bb9a416a28b7d1c44322d7059f60feffa5caf6c5be8447891303"/>
-  <int value="227"
-      label="7006a38311e58fb193484233218210c66125a0e4a826aed539ac561dfbfbd903"/>
-  <int value="228"
-      label="8ed5b4c041b6b293c0e6413015066d318483c901ff69e86a521d0cb25569f3e8"/>
-  <int value="229"
-      label="16a9e012d32329f282b10bbf57c7c0b42ae80f6ac9542eb409bc1c2cde50d322"/>
-  <int value="230"
-      label="da800b80b2a87d399e66fa19d72fdf49983b47d8cf322c7c79503a0c7e28feaf"/>
-  <int value="231"
-      label="68c3692214724d4b55a760f470b4fca8b5e0fe1d729cff22feb4ca88acd39809"/>
-  <int value="232"
-      label="c06c872fc2d0ac08d78d421981fbda4e35500d0946f79894edd21ac29dec0719"/>
-  <int value="233"
-      label="33af58b5589ecea7926252477838ba40247ab37b6fb39e34fcbd552cd5a8c66d"/>
-  <int value="234"
-      label="8adb238554a0cbfc3a11fecc183e3cd2c23d25e7894cf2bbae58eb70a44e7cf3"/>
-  <int value="235"
-      label="98b3f10a025041910f197cf17ca0fcdfed75fb2c8c14a843e04d5656c9ebac1a"/>
-  <int value="236"
-      label="dd9a6bfbf44e17a27f368ac8e067b307396269a747f92e8f2acf2b451e3ffc72"/>
-  <int value="237"
-      label="309f13d49ea66f523241b55524744464e28cc1b82ef79b64e4d581880dcd771f"/>
-  <int value="238"
-      label="98008e2edbb72bad42da2fcb06ac1aaa0b2e6e0c72e8ca204fbafd1bb4879441"/>
-  <int value="239"
-      label="8e8b56f5918a25bd85dce76663fd94cc23690f10ea9586613171c6f8378890d5"/>
-  <int value="240"
-      label="a25a7214c2b6c86142ada39dff2d73d865aa57843fdd2db77b3febf82683de2d"/>
-  <int value="241"
-      label="2896b4ddbe61457183cc7ed27bd78ac50a207f6901c5c52e53dc1676f9bb1e06"/>
-  <int value="242"
-      label="719cf5b36192e7bde650cc91341e6f649dbb8c3ee48bacaa97fa0e05b6374b41"/>
-  <int value="243"
-      label="bcce8e2bbaee71b6358ddd641cbbfc25de454003006271f75b50b726d67c3bc9"/>
-  <int value="244"
-      label="1c294bc25243768913ed4ad5ed61cb02bfbae0bce6e6e72e5f9658f346b42496"/>
-  <int value="245"
-      label="3bde97686e3af51d3f572c4888c12bd1d1e097f12f49ec3c92896551e36f0085"/>
-  <int value="246"
-      label="93a9b3c96aae1cd661215d0c2a065da963d7160d1c694621bcb28c406df64db2"/>
-  <int value="247"
-      label="f6146bc238e8fce0d47b7074c9a26b1aa0f883528510f06d9cfec41ff6ca1968"/>
-  <int value="248"
-      label="2dc9470be63ef4acf1bd828609402bb7b87bd99638a643934e88682d1be8c308"/>
-  <int value="249"
-      label="860a7f19210d5ead057a78532b80951453cb2907315f3ba7aa47b69897d70f3f"/>
-  <int value="250"
-      label="0bdd5abe940caaabe8b2bba88348fb6f4aa4cc84436f880bece66b48bda913d8"/>
-  <int value="251"
-      label="006cb226a772c7182d7772383e373f0f229e7dfe3444810a8d6e50905d20d661"/>
-  <int value="252"
-      label="aa1c2bedb1a508baad7fb3f5e02897b907c748dea9b7908904aadbd0497aab6a"/>
-  <int value="253"
-      label="d9c473cee25f94d1bc6062bd62911477276f064b827a944e064f85d0912d2c5e"/>
-  <int value="254"
-      label="31512680233f5f2a1f29437f56d4988cf0afc41cc6c5da6275928e9c0beade27"/>
-  <int value="255"
-      label="d2f91a04e3a61d4ead7848c8d43b5e1152d885727489bc65738b67c0a22785a7"/>
-  <int value="256"
-      label="3027a298fa57314dc0e3dd1019411b8f404c43c3f934ce3bdf856512c80aa15c"/>
-  <int value="257"
-      label="af207c61fd9c7cf92c2afe8154282dc3f2cbf32f75cd172814c52b03b7ebc258"/>
-  <int value="258"
-      label="809f2baae35afb4f36bd6476ce75c2001077901b6af5c4dab82e188c6b95c1a1"/>
-  <int value="259"
-      label="95735473bd67a3b95a8d5f90c5a21ace1e0d7947320674d4ab847972b91544d2"/>
-  <int value="260"
-      label="a51a2f3a050e838a5050696578dbbedaac1a107ee2d9d48fae505d18d0da5cf8"/>
-  <int value="261"
-      label="6b86de96a658a56820a4f35d90db6c3efdd574ce94b909cb0d7ff17c3c189d83"/>
-  <int value="262"
-      label="ab39a4b025955691a40269f353fa1d5cb94eaf6c7ea9808484bbbb62fd9f68f3"/>
-  <int value="263"
-      label="479d130bf3fc61dc2f1d508d239a13276ae7b3c9841011a02c1402c7e677bd5f"/>
-  <int value="264"
-      label="2dee5171596ab8f3cd3c7635fea8e6c3006aa9e31db39d03a7480ddb2428a33e"/>
-  <int value="265"
-      label="ab3876c3da5de0c9cf6736868ee5b88bf9ba1dff9c9d72d2fe5a8d2f78302166"/>
-  <int value="266"
-      label="47c7a149ca82fa7ba940a4d711d010625c6cb0b748b17016c46e25ce7acd2b0c"/>
-  <int value="267"
-      label="cc4997863c8c48a4cb5c3e6537dc06028d8638be49f5f8a2ba56f2f2c8a8c779"/>
-  <int value="268"
-      label="a86bdab8f480b6eb8942ab9170bdd0991971a7ad135dfbbcb7285f07a7d1e38a"/>
-  <int value="269"
-      label="2da8f9ea3454d21146464a3f9d028dc4c7fbb57b1c52c73c2b0572a2f599a2d3"/>
-  <int value="270"
-      label="0fe14c264b17bb6f0d653e7a70eb363dbf54be158039eddae5c25711df48c103"/>
-  <int value="271"
-      label="5efa073f49426344483ab0ddbbdda5e35972f9c47c74ddf98ec42290b251ca97"/>
-  <int value="272"
-      label="2e00915a9f7be06ab2370c7b7c200c0a96d5ac6a50ce1874dbefde4022d4de8e"/>
-  <int value="273"
-      label="85d26be90d934fccdb4ff7b38d8c79ca7652b816d6a52446ca8428a6b85dc57c"/>
-  <int value="274"
-      label="7f1dec8b0319548a056de5bb521bd93eb74e6a76f28dffb75b45a53b775af7ab"/>
-  <int value="275"
-      label="8a903b600a080b38dfe20dfb6acd23122f64620e5808b9fc8688952fc1a3559c"/>
-  <int value="276"
-      label="84aac093e08c49dbfff8e560759248dbe67135b372b23d2a881d5f99cbb191e8"/>
-  <int value="277"
-      label="6c5cbf02c1849166278f1cd1c83583a147fb7bc95e289b276366935e3153f302"/>
-  <int value="278"
-      label="482f76a2a9346dbb077619bbe1efecd54107e992ff4e8f4d70a39e2405d939d4"/>
-  <int value="279"
-      label="3a6c24e80f681d8b1047cec051c27594f885ba0887a26379092dfef506160e9b"/>
-  <int value="280"
-      label="30ab1bcd7bed1ff2679f71228820420a7063c6cead7ec30d4a016154876dddb5"/>
-  <int value="281"
-      label="ae56d847973d199390e66e4024c9f87d87371e8ba8876af83d1e644f54664738"/>
-  <int value="282"
-      label="93657f8530c596bf909e50da7d8d9cbb36b824cc16ab589137e1438011bc9901"/>
-  <int value="283"
-      label="01d0d8e07bc5a92da7e7b81e9a569fe3a2d63a997dac596002c5dc810cad17bd"/>
-  <int value="284"
-      label="4cc29758a2cb9b50109987f37537cf0c55ba2e6798937307a00296b01dffe44a"/>
-  <int value="285"
-      label="49b80685d332e072c0e7b720032647e842106104e0b1139ab9e811bfb11ec034"/>
-  <int value="286"
-      label="c5ea259c629803508649f02177f63c32fa85cc4ad5c35f0d541c45df10a49fd7"/>
-  <int value="287"
-      label="55e00be277ceb0545299f24fd9f877e2acf32852db43ffcd29bca74b39b4c9fa"/>
-  <int value="288"
-      label="ceb19411c65052c757f941eb826c96941e4d08d096c7db7e7ea3c4f8c13f1a13"/>
-  <int value="289"
-      label="ea87f462deefffbd7775aa2a4b7e0fcb91c22eee6df69ed90100ccc73b311476"/>
-  <int value="290"
-      label="c63d68c648a18b77641c427a669d61c9768a55f4fcd0322eac96c57700299cf1"/>
-  <int value="291"
-      label="7afe4b071a2f1f46f8ba944a26d584d5960b92fb48c3ba1b7cab84905f32aacd"/>
-  <int value="292"
-      label="d1c45377ebdcd618cd1651dc2e02c21d751e5aa9fcd1b3431ff6ecf6a31348fa"/>
-  <int value="293"
-      label="a320f4d534d7be97c1ae8dd0499735bc895c323add2d388bfccf662c23d7f99a"/>
-  <int value="294"
-      label="7cd67c248f69d83fc2f9bb01dcb1f7ad67a363d046043796d0984c3a231f6bb0"/>
-  <int value="295"
-      label="348767cdad3bdd28b2b8dd5351aec30c68cec5cd69d276df3827dbc4f5806464"/>
-  <int value="296"
-      label="5dee74cc343db93f8deaf9e41fbc65b334254b5b23b568fa2814db8b7321ac85"/>
-  <int value="297"
-      label="ea2f9e087eaebbdfc0569eca18364e5236254624854f92e37871b5ee36744883"/>
-  <int value="298"
-      label="805c6696266b96b147468a321eba9eb8b5968f2c477cdd95fdadd1fc63dd614b"/>
-  <int value="299"
-      label="991b5ed1b2fd364b9f634b624b305203f29908be318ef6399222d8a3ef7990e5"/>
-  <int value="300"
-      label="161e83ea32d47641e23cbe0eb413a3e0b06859922a49d1a20cfa05a41e280cfc"/>
-  <int value="301"
-      label="a7e39bd7df609bef3262bf3db4dc8f3814e0db5a7a52156a6d0c35b4dae8a6ad"/>
-  <int value="302"
-      label="06c7bd9553f710e058eb27b15d47dd62d7fd4352d91da96e1efc50e15354b8d7"/>
-  <int value="303"
-      label="3a0d885cb346d8f01fd300af1546f6355c00690e340ed98f346e77b574be3fd8"/>
-  <int value="304"
-      label="1a421223e89bd87c403b48fa616948470d0f2c21ce2ac7bdd22755061c62ba92"/>
-  <int value="305"
-      label="a5204dbb2754b97e3c8a104eacb374a6498a438773c75077f0063c2ceb25d2a2"/>
-  <int value="306"
-      label="7d434d1dada2a154d49f473e381310b83ee58d290a13455182d77f1962df55ee"/>
-  <int value="307"
-      label="a378419d1ae9ebd27b22948044c684ba29bc084b98f965be73262f0f6aaa1c6f"/>
-  <int value="308"
-      label="c954c2c0b189825bb65ddb3ddca080b7dbcfe6b17cade1022bada818336677d0"/>
-  <int value="309"
-      label="05ec0897b21995a4a9899f8fcb06601ade61c04389969d138fe32cd6cfc746ab"/>
-  <int value="310"
-      label="a12574f4eb7395cc630a15fec8db1c7c828f66699d984c8c897eca44c808f55d"/>
-  <int value="311"
-      label="2bb5c28a34c9a37dd9604500ca9b3038d00528b474773a2732aea79e4905c234"/>
-  <int value="312"
-      label="b9182f52af0dd18e3a99ebbae7883d4e4cc7fe2f81fad0d36ca661efc32d0a92"/>
-  <int value="313"
-      label="df530bac9fcd914c252c2fbdceddc6183d4ae8c680ad65f03e204861dd7b1c73"/>
-  <int value="314"
-      label="0d47e98588452cf0778af6af03d442721dc083660a4bb23c697441fe2bb84f9b"/>
-  <int value="315"
-      label="3c84d996722b3c1872f53ddd7717bb2fa50ebfa07b3f3b4a395335c56712fd69"/>
-  <int value="316"
-      label="96475b35acb1c9303a90bd1dbf57418f78e29af11c4de8c8cba2e5f9309e38d4"/>
-  <int value="317"
-      label="18cfa64518e916cafe985561513cab7a897a54bd23b8e26874c5c7cbd1249cfc"/>
-  <int value="318"
-      label="3c196f84e2a0c61fec18bacabd31783b574517aad8ebc6ce6d1d7dc82b3c50df"/>
-  <int value="319"
-      label="931f1cf03a6f84c30ff3ad869be3c21a410191cc98ac0afc9d4e8b89bd869ddc"/>
-  <int value="320"
-      label="522c3960328026a1e322389a8a08fedc1b86d9c2b59b33484b77f7ce790635d7"/>
-  <int value="321"
-      label="8991e219ce9f74479eafedb3535836121dd233ea768afb9d9ac8b4a22381a8d5"/>
-  <int value="322"
-      label="881a1b9edf69ade141839ae8673d31b4f4d47f126ca08a79ff065dc9a690f4a3"/>
-  <int value="323"
-      label="62a31a5c730dba674ddb25de33df143644375b49af07878a667b813491c73971"/>
-  <int value="324"
-      label="51b6ea6478687b47d963b6149059780cf08a4f02f042d61b5bd52639095ee910"/>
-  <int value="325"
-      label="6cae87c558d2441568e38270a8dd8ff484a259dc4f3ce94ccf434c1fa99811f6"/>
-  <int value="326"
-      label="d4af6c0a482310bd7c54bb7ab121916f86c0c07cd52fcac32d3844c26005115f"/>
-  <int value="327"
-      label="f6b59c8e2789a1fd5d5b253742feadc6925cb93edc345e53166e12c52ba2a601"/>
-  <int value="328"
-      label="4ba6031ca305b09e53bde3705145481d0332b651fe30370dd5254cc4d2cb32f3"/>
-  <int value="329"
-      label="0999bf900bd5c297865e21e1aade6cf6bb3a94d11ae5ea798442a4e2f813241f"/>
-  <int value="330"
-      label="1462009b2de65d6d4d39be892bd2c186490531ce6590e48fe196070d317b60b0"/>
-  <int value="331"
-      label="e26613a578e158c2a44e4fec41e6f37a0a991fe1a5fe736c303f4420a90fb50a"/>
-  <int value="332"
-      label="498bc0cd5a49b714071ec76a41661ce2f27fc39fe4168bc7b7799a0ae25f6528"/>
-  <int value="333"
-      label="9d98a1fb60538c4cc4857ff1a8c8034faf6fc592093f619994b2c813d250b864"/>
-  <int value="334"
-      label="a2dc98ca7cbbee1822b25b267bd5ca502fa7b0cf4fff0703ee6a416703f3c7ea"/>
-  <int value="335"
-      label="f5857d8862bc2ba3c9ddca3f84146dc8d81f4d579d2b387bf60065381ee641dd"/>
-  <int value="336"
-      label="9119e2f413579777954991703eee23a04523a312b5c65f7f9374aa3100ebd8e7"/>
-  <int value="337"
-      label="af6ab51b7bad1dedd533eb59332b6227d6557f20b4443216db735b92280c7a44"/>
-  <int value="338"
-      label="086dcd7bcf864aaad5ef8c1c577bb68a131e055c93f63b9c47ee26eef15be7ab"/>
-  <int value="339"
-      label="232cbe2d9e6994c1ceb7fbee23ab1657defb6b3564726f1e78951cef3a2b095d"/>
-  <int value="340"
-      label="431b79fd9355d10dc1b50dbf6a6b62d7a5b6d356541c27605255ca4ca79420c1"/>
-  <int value="341"
-      label="7c3b46d9be8f2741f980039521858e4cdd30774fb32b3b21ceea06aa79c6aac6"/>
-  <int value="342"
-      label="9dc38a9edcf82842b674da186b6d6215ab9e2ec6d72f57b08a892728c31431f3"/>
-  <int value="343"
-      label="283310819f5e09204995d8ad9ff6fc10746297b5c0ae06bdd1e1124b10a0d7ad"/>
-  <int value="344"
-      label="6046136879e56450400f7db2ecd0df1b88f667c1e3fffc52964ff9e2e48e85f5"/>
-  <int value="345"
-      label="e85fbf8b9a2ea4909dce0fb5b2fe5f5877343d27d58a410a8b237ab675a2ddaf"/>
-  <int value="346"
-      label="5aacf1b965e853010fcb2a110317d5fce3ee351e9cc95bf444a571d7b8ef9162"/>
-  <int value="347"
-      label="9546ce00e03dd61aca58c5c8dbf38a111bad6406c91d7422e7f4c40a0cb58f18"/>
-  <int value="348"
-      label="b4296d5fe60e52f3f0ff99da75af5e7e62599f99ebe0fa413f66e6b425c3d09f"/>
-  <int value="349"
-      label="7f7c88a77d4d3b44c33b3c030bc83f1a26c20d49177ca7745d91d9de17e08f14"/>
-  <int value="350"
-      label="faddde04bcf08ca8f4e22efd2afeade6bf3d850ae47be96a82d539494f120cbd"/>
-  <int value="351"
-      label="20e24a5a3393d6c3adc384faf95152e1f9aa7222774028b53c5a34ed0c6cb399"/>
-  <int value="352"
-      label="4697a5abea0070a395456fd358e91f72f227d5850933227f1e0bc79ff847bfac"/>
-  <int value="353"
-      label="463dbb9b0a26ed2616397b643125fbd29b66cf3a46fdb4384b209e78237a1aff"/>
-  <int value="354"
-      label="9e5a34b08929bc0a581c8936aafd6ab7517bb15188b4f6fc02c45906f71595b0"/>
-  <int value="355"
-      label="b3182e289ae34ddf2be643ab79c244301605fa0f1eaae6d10fb929600af84df0"/>
-  <int value="356"
-      label="a798d92f76c9c6755e5f55f86cd14aedcc0655371e27ccde0377745ce3c50013"/>
-  <int value="357"
-      label="004124ad6037fd5f3319e7a23d4d9c811f5598d66c4754155b0aaa9e8f00621f"/>
-  <int value="358"
-      label="c90d009c47eeb9f2a29ae848f5d930f2b41ef5edbc5c5695c1414345c1dd67b4"/>
-  <int value="359"
-      label="2a4f49ee7701a395ac932e444292671588ade21259ce296e194940368702ea7f"/>
-  <int value="360"
-      label="30b71c4f9122476e761e620eec42bfa5f84c493cd49bbb1834b26e555f60de40"/>
-  <int value="361"
-      label="ef53ffaf0ceb040d077f5bd80a9deef6d4507fdb6f9bcf8c3594bece7ebdb025"/>
-  <int value="362"
-      label="651bd66f5c3dc637957ef5185e4fa671c21654b1c0ea49384f44bcb256a5084c"/>
-  <int value="363"
-      label="f5e19c8e14fe755f551cec2b7113e7c98023b176ebe6c1abcf872b2a7b932304"/>
-  <int value="364"
-      label="a74b4b6a2eb55b9864c04ecb16003ff5db5b51e42cf859f95e9d0a1dd4644096"/>
-  <int value="365"
-      label="d92405c46d912a563e43287f56cd410a1cdf6367c57c9ea7c5cae039dcbcce50"/>
-  <int value="366"
-      label="86c84b1c3a66f4285af797052467e3ed236fd2986f033c02c4771be0b970482a"/>
-  <int value="367"
-      label="d1ecacca44012c3e1e6d1b39dd2968fc7fd3127aaa57ab5182a3beabccd7a3a9"/>
-  <int value="368"
-      label="3fb63c29f47bcc4e6aadb3577ce7ca8543e0bbaba553676b8fd161295bdb9011"/>
-  <int value="369"
-      label="e0ef882da48ab0b7efb0d9ba15b2717dd08f043c25ac09b56b8b57fceeb5a35d"/>
-  <int value="370"
-      label="8ab4e88556cbf864a5e9fd50171cd4ed8424e8f0801b99e236c810915950ae4b"/>
-  <int value="371"
-      label="a4b89bb70656ea498f2d9e00a497fdb9dcd20b81b8938e952bba2df9f65729c3"/>
-  <int value="372"
-      label="bedd8bc97ea86497195a078a999a237a060aebae07bc0a0b9b778982ba5f62f4"/>
-  <int value="373"
-      label="c42533d3af4998f5ad9f072521d85d472fa7ffdcfc588c8247b337dc77109389"/>
-  <int value="374"
-      label="d646f3ea2d7003fcaa77ad219136c78e024a6f2e2307dfb8cfa97a171373ecdf"/>
-  <int value="375"
-      label="8b49506a3461063ea8cc13ffce2b581de15a94b957092a93123467b89ed802e2"/>
-  <int value="376"
-      label="6d28f9e405148b69027da990815211c858841c543feced008c238021983c095a"/>
-  <int value="377"
-      label="ed1b229e0e0875021c1f1760c3407fb1d6608eda7add71a3e3275ced09690f7c"/>
-  <int value="378"
-      label="87157a7585f4d03b00a398461e164e4806e1b3f46d03afbdc9def4e4778be2e9"/>
-  <int value="379"
-      label="22050a92836481c2f3c1f8417d37447a167007ac9ba64ea228cb6a1e14c64b8b"/>
-  <int value="380"
-      label="f73be5eba536912c557fb855517ad1ee0487bd8f63498c3949164177ba06c5de"/>
-  <int value="381"
-      label="4ba24996ddee6f8e1fcec0aa9eccfd3aa5477b3ef8f5f85f0a06073f97522857"/>
-  <int value="382"
-      label="acf7ad98e6f065866e6f8cdf0ceb6f7481f6957b6dff823f6b94d79f01a61c39"/>
-  <int value="383"
-      label="ae2033b3082825a703e5a6adc3221a86854aa411db047dd5f53eb84aa14bdc01"/>
-  <int value="384"
-      label="8d775a4f93cd20c18306144f42b569fc2a897eaeaec3d3ea3cb025d1ad4d28e7"/>
-  <int value="385"
-      label="5094b73b736adf73a0cbf43e27bf14407b4a36aa363a457fce33949ceba8e649"/>
-  <int value="386"
-      label="af110f6b5ae8b767eac6e0aa273f3816e7a40a644edacb4398146356e77509d6"/>
-  <int value="387"
-      label="f7aff41b2709f175f8aba17e567b27046b2dd54bf6e7e263d3295873437b9cff"/>
-  <int value="388"
-      label="112432e4bb848c45549fcbf0c710c566d0082bbbc4e9b38e6c76ad46448128fc"/>
-  <int value="389"
-      label="7016270b60b28c6e177edebd718007dfd3310c64a737b7db01a07690c343bc27"/>
-  <int value="390"
-      label="ad304c884a5d376bd195209a14c39e07f0d3f5cf893d802b053e1b926e55d774"/>
-  <int value="391"
-      label="94b94bbf9a0726f17b0973af6d41e9fb2e7099651bcbefddd97b0a5f2aabb0dd"/>
-  <int value="392"
-      label="8a42eeadbc8b21a35c4b3aadd7dfbcbd2ed1b1da12e8c45a534da90607e564fd"/>
-  <int value="393"
-      label="ef4fa1c630f04950e0e2d10dc19f149d08ab46dec95da3131cbaea8af8ea3027"/>
-  <int value="394"
-      label="913119f2cd3f48aca74ea6443ee50e0de1202d9c54f336dc9300affe97d4577c"/>
-  <int value="395"
-      label="7e6acd853cacc6932e9b519fdad1beb515ed2a2d0025cfd398c3ac1f0dbb754b"/>
-  <int value="396"
-      label="979f6f6a8a41c421cc673473d58a6379817be73d2e524698c80ffb66a149d089"/>
-  <int value="397"
-      label="c7f584236d86395e8f6f82c010886a2c56e071a6a1c3ed2876b8a3a72c5efbb5"/>
-  <int value="398"
-      label="202665e4c5c380b4490a81773db5dba62a90db6f5be6e0e54d11992fb1e655fd"/>
-  <int value="399"
-      label="dc053d027fc186e7c41cd193af30fc09794eb9f3d9e6736dce041440d876a801"/>
-  <int value="400"
-      label="15bb28d9207e13f8bc9557dd785eba773bea944e04d7e08ff8aa55ef3194aa20"/>
-  <int value="401"
-      label="58a2a698d86fd8497d41f68e4caeb4a98874f433da913dd26c5ca44d08ff72fe"/>
-  <int value="402"
-      label="c9905b0ee01202293ca026e64f08412442c5504c06e44ca7e9726d61f20e4089"/>
-  <int value="403"
-      label="44a3d80d3f5348596d80a09842c23a39774439f8b0b919239d2a03dac5ce5213"/>
-  <int value="404"
-      label="bfe82909872e4434f115c51a56168019594d0e03dca363d9f3b4839d0babcde5"/>
-  <int value="405"
-      label="d5597ea3453a6261f5d42eb9caf5bdb4e38a1edebdb5bea6d7c0bc1a8abecab2"/>
-  <int value="406"
-      label="5143e47569a1d5fc867893e0cc412c41f55715da78e59e9f8e43770008ca42d2"/>
-  <int value="407"
-      label="9efd911d6ff46f1831111df3c54cd2611cae2398ff7386d1cb6b4f32e3337ed6"/>
-  <int value="408"
-      label="b656a4343831a2acf11eeabc3a44b97025fffba2b910da8714cf827d81be10c9"/>
-  <int value="409"
-      label="42a70984ffd399c4eaf0e702a44bef2ad8a79b8bf4648f6bb210e123fd075793"/>
-  <int value="410"
-      label="85a3d81d2ad0c79df0a79684e0e2666009a09de15760ea1d76cf0ee7b2825dbd"/>
-  <int value="411"
-      label="02376d0908ac23041cc7d666d9daf192554f7fc36317aa9cb800908616b28af8"/>
-  <int value="412"
-      label="b083ff536f7f48a9081e294a0187b53e819771402d9d4810306de031024e5f46"/>
-  <int value="413"
-      label="508f8c6178af329bb6bb753ab943d9023be796c3adbb6c5cd4664b66feeccae5"/>
-  <int value="414"
-      label="43c74262f7492662d2459bcc9899bac54a4ecc01e1a3f5e76558992b40152418"/>
-  <int value="415"
-      label="bf01c35f337113f167b4a50186765e7b1e3890af586328f185cd0d6bae813521"/>
-  <int value="416"
-      label="1eb9cf901f0858aa17c399babebbdd8cb303a4ef4e1220c493cca2f75a3f914e"/>
-  <int value="417"
-      label="19ad98de02155d7e33e9dd21f0e45610fd11d28044b8318bbebf9f6337888df0"/>
-  <int value="418"
-      label="8bea76ebd6137aff9f1ecc3c08caf1dec47db91690d5754c4e9f15232c0a2e78"/>
-  <int value="419"
-      label="1b8a89531701608c9ef3c65f5d60a948b1badb9753622a2e81c0a4a284be63cc"/>
-  <int value="420"
-      label="3ea7b5c045a99a9771e2dea8e8098ba2732d17ceee82279552feee905530f35f"/>
-  <int value="421"
-      label="6a7b1482127002f9005a87356e1dc3e00b70bbbfa795024ff8beff74c4259b75"/>
-  <int value="422"
-      label="2364d692dccae13da56ad4a07c1325dc575215ff1a071681dfca5dd6ed7c8452"/>
-  <int value="423"
-      label="816ba0bfdf5fd64d568ec0d052f71164d9e2ccae12e0219ed6cd81e7e845fb84"/>
-  <int value="424"
-      label="a1d45d06297341b1f3a735cfa38f283e6879fec06281a361e5f417cc70d29dc9"/>
-  <int value="425"
-      label="972fbc6d55bfefb1abe3758ad7d67a349bbef80c06f1d85001dfb9101b9abc1b"/>
-  <int value="426"
-      label="6a436b58d9d830e8d5b8a642505ad6b41406adcd6894d9414f7be0a1467badb7"/>
-  <int value="427"
-      label="2fcc99f5c9d00f9a20da6131dea5c027d92636d68cd9cdbe95290a3c408919e0"/>
-  <int value="428"
-      label="66b00539826a37484930191e028f62dab1cbc89b3acd472dc4e5905e47bf7364"/>
-  <int value="429"
-      label="689bf45b3083fdead55f147fd105e3cf218ad58edf3e4b301c0c5eeea6cf210d"/>
-  <int value="430"
-      label="b5ec35baab538884cfa8dd97376b102f03e53b482c64100c250722ae9b042cbc"/>
-  <int value="431"
-      label="9ea9fe274537f4f935642cde824fd77eb0e125cf118ab9b4c219f6cbf959b18d"/>
-  <int value="432"
-      label="b16cb1ba529a39e2dfd53b3ff5a79f1904614d83e31304f0278bb40b38cf7824"/>
-  <int value="433"
-      label="0f9c1299557598cf7521bcc8798420a155cec1bb23a57ac37f5120fc9a2057f8"/>
-  <int value="434"
-      label="99333c3a665cf0efbb7488b3807b8b65f87b5b29d6880f028edc28442eeae669"/>
-  <int value="435"
-      label="782d7e61e1323d2aafb877be34ee1de0c1345136d4fcb3c945937f6a67b412fe"/>
-  <int value="436"
-      label="3d8d061edcf7b3d45995ba4341328d1be7b7eb4e9d14fee70d2f18ad68bea7c5"/>
-  <int value="437"
-      label="78cf3d3c72daf91cc51b871357a551cf95b837d074c270b08facd463a8d39bb3"/>
-  <int value="438"
-      label="2d6d690c16b11853884bbea2723725267e3f9b54a6cf07ad4690ab1e7cfb75e8"/>
-  <int value="439"
-      label="8e15d426cd04898f218be2e5fe3784f375094cc435dc61ad86c4a3c01511dbe1"/>
-  <int value="440"
-      label="58044626c34c1a7b158ddb676d9e2e65443d818dab3116231e2d62ab6426a0b7"/>
-  <int value="441"
-      label="29e7fdda489e46ee486efd75acc48f251932dc9da1872b31753cd64719567aa5"/>
-  <int value="442"
-      label="111c24a243061da76e57e3b1243eda90879ffb750552395443fa8c34dc0ed737"/>
-  <int value="443"
-      label="c53dad9e53ae27ed95f0ea7a9203f7bf56eff0f8e1ce960cb4761b968342e34e"/>
-  <int value="444"
-      label="4376a99396769fd487240ee8b573ad49706a5b9473616acef38409e91586dc1e"/>
-  <int value="445"
-      label="e156445fa20c32ad00937b27d096b8963bcc863950333a877e68fa69707a03af"/>
-  <int value="446"
-      label="71ed918a7ac6d17b3849c20180b3e7334691bc5fb73377f0070afa0be789b2d1"/>
-  <int value="447"
-      label="439c19ff3edb265ef1a920f74a4802d3dd95ace024e21e5a6ce8e064dc1566cd"/>
-  <int value="448"
-      label="63f1a6f79d6e730d10432e6308194ff7bc28850adf2badf789d971385d8512ee"/>
-  <int value="449"
-      label="a4cbf48516af3160ebc62acac6e7f258609ed0891535010c16692493a9fe1fbf"/>
-  <int value="450"
-      label="b213a9cbaa9a8831ac0b3aa80e9d15856cd43a7cc2e0bac5fcb84a24751a8a78"/>
-  <int value="451"
-      label="abcadfa35ff835cb3a0a0b86400622b80d5e80c765bc027f1b1c4e0a620f5e1c"/>
-  <int value="452"
-      label="676b9ff303ede180fb95a4736fb4d3153032c014444f63a2074c41b98b51e0bd"/>
-  <int value="453"
-      label="a59d2f09c8b168cd9afa3bc3eb4db0d7a43588d523287f2b83a822eb33709170"/>
-  <int value="454"
-      label="4e6c1616637199b5077a80ad0c2248c725e576fc8a719989456bc9cafddb7524"/>
-  <int value="455"
-      label="a76e2949cb87f6236b5f68c690747587d6448ea21cfead7950084ac015190b25"/>
-  <int value="456"
-      label="0206ead163b10ea2f8620868ebd7a15f64a20250d16cd57d6e87c4fff1a2197c"/>
-  <int value="457"
-      label="49cbd83c03cabfa0713b97bc96481d035fd4ebe06f07fab5640ed9232d8110b2"/>
-  <int value="458"
-      label="33fa5a5300613d466e6f85c8051695bed5d1fad59f25e040acda0472a74f3c20"/>
-  <int value="459"
-      label="380739620e13335805eada8f9f8b81554d3bd3c0017f3632c2677669cac7a2bf"/>
-  <int value="460"
-      label="244803cfa35953385d06657ac4e5ab4f2bc0405277be662adb905e1498b1defd"/>
-  <int value="461"
-      label="3ec18dfeb894a9ea20eb2cd40c693e2a29144fe2ec60b4f7b89026040b39aebe"/>
-  <int value="462"
-      label="9962ab1699b0eb7c7e8a578bc79893042031c1158c633613199a90b9652a2a75"/>
-  <int value="463"
-      label="8e8046ec4cac015a507ce0d2d0154a4b40e8e42b3165cfa546571435112d17e5"/>
-  <int value="464"
-      label="57a742a88d3e18fc0bc611bc7976c22edc50011757512b1a7e2e1d069b3ecba0"/>
-  <int value="465"
-      label="b489ccb224b9a6b81dd274ceaf5209c252998c9a76af48e4f4c50a0728461825"/>
-  <int value="466"
-      label="42a807cec5ae9c0f03b40ca043ac70468b5219bd75cc5bbea51d921dd100156f"/>
-  <int value="467"
-      label="f42352c3cc3d84b8518989d647c88ca301c88fb991938bbcecc9ee60e565d377"/>
-  <int value="468"
-      label="5c41a73ab2c35dfcd771f6fd6e3e8fac9b469d386cadda56a95b646eb48cca34"/>
-  <int value="469"
-      label="1255cabe8152fa64df942f7a47417e29f96c1ce11bf8c84ecbe2815cc1280810"/>
-  <int value="470"
-      label="4ef7dacf77edb751f704035fb5c6c442351ec7220af90bdf82fd047bd3c24187"/>
-  <int value="471"
-      label="3329bfa13b6007ab5fc3713f0acb289426e2fbc99cc5c110a914b139571600b6"/>
-  <int value="472"
-      label="d3980aadd21638c70d74a4bb1f8ab5e11724e62ed408f9fa8d3d4d916900286b"/>
-  <int value="473"
-      label="7d6c3ebf9ea735d1854beea7cb941ab1e3503515e087bbb5be695d05f2f556e4"/>
-  <int value="474"
-      label="f2a4e6b263d0a552adff5d85dc96b5820fd66aa0b18228f48fdb087c8db34133"/>
-  <int value="475"
-      label="b89bcbb8acd474c1bea7dad65037f48dcecc9dfaa0612c3c2445956419df32fe"/>
-  <int value="476"
-      label="4f7162b974491c98585ec28fe759aa00c330d0b465190a896cc4b616231831fc"/>
-  <int value="477"
-      label="21ae412566324725ffefc1dccf88f16f8d6bf4dbbb37fe8caba47e8d66c2cdf9"/>
-  <int value="478"
-      label="9415b25dba3bbd711439e2a9964b7a5256aff3b05c772c8a34e6c93566aba63a"/>
-  <int value="479"
-      label="ac447dedd0432aab9c070f2cca01b6dab09bef07cf4ca6aaa755634f857b315a"/>
-  <int value="480"
-      label="67a84264d42e204a9a5b0a3667b951db22c505df95ed983b5e8c4d1fce77af43"/>
-  <int value="481"
-      label="3ee6b341402851b27e64021a3023aac7c1a0d2def27d5bce5c2dbeb0b22dcc71"/>
-  <int value="482"
-      label="5899d913ead119b9cdb7ba2f30efe0df68ad2cd225bdf493e8323a25aa4dbe23"/>
-  <int value="483"
-      label="871a9194f4eed5b312ff40c84c1d524aed2f778bbff25f138cf81f680a7adc67"/>
-  <int value="484"
-      label="55f77de41c03792428f8d518c55104225be43a5598d926a528ad653e1ccec7bf"/>
-  <int value="485"
-      label="4179edd981ef747477b49626408af43daa2ca7ab7f9e082c1060f84096774348"/>
-  <int value="486"
-      label="9847e5653e5e9e847516e5cb818606aa7544a19be67fd7366d506988e8d84347"/>
-  <int value="487"
-      label="682747f8ba621b87cdd3bc295ed5cabce722a1c0c0363d1d68b38928d2787f1e"/>
-  <int value="488"
-      label="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"/>
-  <int value="489"
-      label="282fb5cfbaf01518d9704de7884d7a25ff01cf882e994290d5995d5eb6c44988"/>
-  <int value="490"
-      label="fd371bea9755ff60c8828c849b8e5215de532d61b009855fa0ad630d90eef82e"/>
-  <int value="491"
-      label="d49c6f289cd056519492480f192f00a6fc7c1862dab2e7b5d8e05f6678fae141"/>
-  <int value="492"
-      label="cbad7b1d384849df0946b7ee8e7f5f7ce3aed876fda7bc9d30d8b16f29ff2c53"/>
-  <int value="493"
-      label="e0c780c629903e126f1d919570dce7c496f85f33aae66b9a3147ee75f8d1620a"/>
-  <int value="494"
-      label="376a1a7082a593dccc20d561d119e9ab8d30f11cc321d0a37fa41f0df284e01c"/>
-  <int value="495"
-      label="8d417db2dd8bf5e3084d1e3f196d583849d81bdd4c00c70b9d39369e96b8c782"/>
-  <int value="496"
-      label="b7408b4d2be0238ba37004dd34e276c6019bd2f24c9db7d4980f5f6c359a4bcc"/>
-  <int value="497"
-      label="eabc185c4e82d942b1a5978ba3c0181487d6b3b9974e5c49f72f6d0bd9637150"/>
-  <int value="498"
-      label="2541e53ba5b3b07acbe7097ac4a03e040c11cf7a6d4a67cb213d558b50167a06"/>
-  <int value="499"
-      label="68ded9a203ff6e367e12aa49977cd200f7127a800faa6f859f0bafed8286a4fb"/>
-  <int value="500"
-      label="36d7c79f3d089a0ff79972d90923dea5ca76b4ccbaf7c2751cb152e9494f52d0"/>
-  <int value="501"
-      label="be3280c6863c770a33c9040bd97d5540b216d1d91db8b088ceac1197dae1d660"/>
-  <int value="502"
-      label="c5750bf85f459fb70e2b6cd1898d375e92d7938e47a6e034cce0c12d30372ccd"/>
-  <int value="503"
-      label="22a36994f28f2fa3b16ae872a79dbb12a982da5b824d7ae434f96178ac540351"/>
-  <int value="504"
-      label="f26cdaa1c48e2d369eaf24993a424f8290983af7094a5bde9c7d44341f2e2428"/>
-  <int value="505"
-      label="c372f6d18ebee5aa23d9e919f3e6be98488ec01607df3162fc192e4b1346afb3"/>
-  <int value="506"
-      label="68aa635451d83962167e88fb08f8678d73aec66fc559462137cff9d1bc3d3871"/>
-  <int value="507"
-      label="b2f7298b52bf2c3cac4ddfe72de4d682ac58957595982f2b62301af597c699c5"/>
-  <int value="508"
-      label="35f53ce1264611e03340fe37e1ec7d4cc986c5613dca70fd04aa44545f2daf28"/>
-  <int value="509"
-      label="9091e31fe92546a5f5e1b3ed4071f4440b840c1e80dbfcba7a7ec6d5825f0b24"/>
-  <int value="510"
-      label="786ffa578618c3b9a311175e50816f4dda0605c3869f296ebc5943bf09f4e904"/>
-  <int value="511"
-      label="828b0eeff24654e8ff5841a29dd5d4e3ed30952ca43425a79283407208d39d16"/>
-  <int value="512"
-      label="497128fc90656b87290482b223efb72240fe9c421e79938de5f8110cb0be9056"/>
-  <int value="513"
-      label="2e06cae1fc20b200e6fb748557a4444bec9317dfff2e4151669e0f7944f0a9e0"/>
-  <int value="514"
-      label="122312c081949106b7049f3febf199c010ada13e3281cd358a41e7bd09c829d7"/>
-  <int value="515"
-      label="1134fd81561a2818eccfffc2e440a0cef9a40e2926c08299804d738b0a97f63d"/>
-  <int value="516"
-      label="79caaf5347e6e4a94c8e78a98496fc74020f809ede13f220fab6104c8ded329f"/>
-  <int value="517"
-      label="fde8999a5e427319835c89a17d64a2dcd13a851c0916c4c547b6d8f7a6437d94"/>
-  <int value="518"
-      label="453b74809b69019627f2f843001db5950cdd1d45371053e7f3dfdbc3714113c6"/>
-  <int value="519"
-      label="1f3c9fd4fdbb50a055bcca7fe5a581a92099cef1e9e476d6baef0c910831c7b3"/>
-  <int value="520"
-      label="c942262c0c7c0a95bb152b71c42556ddbe9a04fa8378373550d2b7ce27d952a3"/>
-  <int value="521"
-      label="42431627ea76cc78697f915e3455b1b2ec82ff2f6380ee6423ef3c0840b7e631"/>
-  <int value="522"
-      label="693c9aa6b245b3b0261637750863eadb6c248a16e52d6f4bc90c86bbf32d7042"/>
-  <int value="523"
-      label="a02fafa192c8cb81cb1341554f9c05b71cca2a890b0d1298d683647c961efbdf"/>
-  <int value="524"
-      label="e04a022ce32f4ccf2c7f6046287b828a32a909f5e751447f83fd2c71f6fd8173"/>
-  <int value="525"
-      label="ae7f962cb9e6a7dbf7b833fb18fa9b71a89175df949c232b6a9ef7cb3df2bbfc"/>
-  <int value="526"
-      label="96352d0ad875c027db82d599baa8d42e5c472649981eceed3bfc65f4c81fd5c1"/>
-  <int value="527"
-      label="e14e51891f3492243eea613bc2c814d47224b224c57d38169e958e30b3dedee4"/>
-  <int value="528"
-      label="b15ac9561204756124b9c4d3fe406d93833ff66652f67fbf139f5bbf030a0e64"/>
-  <int value="529"
-      label="a495c8d110e8b9e200f370aeda3ff92ee43f8e3d4ec0db1c0dc58bd762880ba5"/>
-  <int value="530"
-      label="d6ec6348a7c4d42ac48d9c43145a8cd71971362363267c6673a77b8a8573a66b"/>
-  <int value="531"
-      label="6a97b51c8219e93e5dec64bad5806cdeb0f8355be47e757010b702456e01aafd"/>
-  <int value="532"
-      label="48a8a7ecd03a83b26aec7574d09d6453e95f90360634ce204bcbd473997d4c05"/>
-  <int value="533"
-      label="c2b3c31a4a29850aa8f3cf472a1169ff71b416579f6a4482ec7744b83df988ac"/>
-  <int value="534"
-      label="fc784300ec8df4d3d1bad763835182918d52a9ff0238bdf695a1cd9bdb98321c"/>
-  <int value="535"
-      label="762195c225586ee6c0237456e2107dc54f1efc21f61a792ebd515913cce68332"/>
-  <int value="536"
-      label="681dc482c296c8402c6ebb20e68309a3bc846523ae34b984a84ee697a3312db7"/>
-  <int value="537"
-      label="f0011f92fcf9be36c7a5b36e7bc862ab20e94ef36fea8a561db0a8d7750c1f51"/>
-  <int value="538"
-      label="fee8af929175687f4638a3fc983db8ecd0e5e2a83e737f3fb77b4c22fcbac0a6"/>
-  <int value="539"
-      label="bdaccbf2e8b27c0c02a689ee866c9b86ec04442afcdddd5d4ec36def21e761dd"/>
-  <int value="540"
-      label="581cc15821169694c39c2991b53e93ab945a42b076661774c2ecf38a3323acea"/>
-  <int value="541"
-      label="bb0ce7040314a143dcd10e65ccaeef7010e1b784d15d195d77b5601956bf9e3f"/>
-  <int value="542"
-      label="de7b6932e9c44582ce0de07abdab7eea90c75d6d2a07331df57bd5cb88553d13"/>
-</enum>
-
 <enum name="NetworkBlockNonManagedCellularBehavior">
   <int value="0" label="Admin allowed only managed cellular networks"/>
   <int value="1"
@@ -58254,12 +56407,6 @@
   <int value="101" label="7115"/>
 </enum>
 
-<enum name="NetworkConnectionCost">
-  <int value="0" label="Unknown"/>
-  <int value="1" label="Unmetered"/>
-  <int value="2" label="Metered"/>
-</enum>
-
 <enum name="NetworkConnectionIPType">
   <int value="0" label="IPv4"/>
   <int value="1" label="IPv6"/>
@@ -58331,16 +56478,6 @@
   <int value="3" label="Dual-stack"/>
 </enum>
 
-<enum name="NetworkLocationRequestEvent">
-  <int value="0" label="REQUEST_START"/>
-  <int value="1" label="REQUEST_CANCEL"/>
-  <int value="2" label="RESPONSE_SUCCESS"/>
-  <int value="3" label="RESPONSE_NOT_OK"/>
-  <int value="4" label="RESPONSE_EMPTY"/>
-  <int value="5" label="RESPONSE_MALFORMED"/>
-  <int value="6" label="RESPONSE_INVALID_FIX"/>
-</enum>
-
 <enum name="NetworkPatchpanelArcEvent">
   <int value="0" label="Unknown"/>
   <int value="1" label="Start"/>
@@ -59276,21 +57413,6 @@
   <int value="8" label="H2 pings"/>
 </enum>
 
-<enum name="NsswitchService">
-  <int value="0" label="Unknown"/>
-  <int value="1" label="&quot;files&quot;"/>
-  <int value="2" label="&quot;dns&quot;"/>
-  <int value="3" label="&quot;mdns&quot;"/>
-  <int value="4" label="&quot;mdns4&quot;"/>
-  <int value="5" label="&quot;mdns6&quot;"/>
-  <int value="6" label="&quot;mdns_minimal&quot;"/>
-  <int value="7" label="&quot;mdns4_minimal&quot;"/>
-  <int value="8" label="&quot;mdns6_minimal&quot;"/>
-  <int value="9" label="&quot;myhostname&quot;"/>
-  <int value="10" label="&quot;resolve&quot;"/>
-  <int value="11" label="&quot;nis&quot;"/>
-</enum>
-
 <enum name="NTPBackgroundImageSource">
   <int value="0" label="No image"/>
   <int value="1" label="First party (NTP) theme without refresh daily enabled"/>
@@ -60466,46 +58588,6 @@
   <int value="5" label="Expired because the device was suspended"/>
 </enum>
 
-<enum name="OnTransferSizeUpdatedFrom">
-  <int value="0" label="CacheAliasSearchPrefetchURLLoader (Proxy)"/>
-  <int value="1" label="CorsURLLoader (Proxy)"/>
-  <int value="2" label="DelegatingURLLoaderClient (Proxy)"/>
-  <int value="3" label="DownloadResponseHandler (No-op)"/>
-  <int value="4" label="DriveFsURLLoaderClient (No-op)"/>
-  <int value="5" label="EmptyURLLoaderClient (No-op)"/>
-  <int value="6" label="FakeEmbeddedWorkerInstanceClient (No-op)"/>
-  <int value="7" label="HeaderRewritingURLLoaderClient (Proxy)"/>
-  <int value="8" label="InterceptedRequest (Proxy)"/>
-  <int value="9" label="InterceptionJob (Proxy+Work)"/>
-  <int value="10" label="MimeSniffingURLLoader (Proxy)"/>
-  <int value="11" label="MojoURLLoaderClient (Work)"/>
-  <int value="12" label="NavigationBodyLoader (Work)"/>
-  <int value="13" label="NavigationPreloadRequest (No-op)"/>
-  <int value="14" label="NavigationURLLoaderImpl (No-op)"/>
-  <int value="15" label="ObjectNavigationFallbackBodyLoader (No-op)"/>
-  <int value="16" label="PrefetchProxyProxyingURLLoaderFactory (Proxy)"/>
-  <int value="17" label="PrefetchURLLoader (Proxy)"/>
-  <int value="18" label="PreloadURLLoaderClient (No-op)"/>
-  <int value="19" label="ProxyingURLLoaderFactory (Proxy)"/>
-  <int value="20" label="ResultRecordingClient (Proxy)"/>
-  <int value="21" label="ServiceWorkerNewScriptFetcher (No-op)"/>
-  <int value="22" label="ServiceWorkerSingleScriptUpdateChecker (No-op)"/>
-  <int value="23" label="SignedExchangeCertFetcher (No-op)"/>
-  <int value="24" label="SignedExchangeLoader (No-op)"/>
-  <int value="25" label="SignedExchangePrefetchHandler (No-op)"/>
-  <int value="26" label="SimpleURLLoaderImpl (No-op)"/>
-  <int value="27" label="StreamingSearchPrefetchURLLoader (Proxy+Work)"/>
-  <int value="28" label="ThrottlingURLLoader (MaybeProxy)"/>
-  <int value="29" label="URLLoaderClientCheckedRemote (Proxy)"/>
-  <int value="30" label="URLLoaderRelay (Proxy)"/>
-  <int value="31" label="URLLoaderStatusMonitor"/>
-  <int value="32" label="WebBundleURLLoaderClient (Proxy)"/>
-  <int value="33" label="WebRequestProxyingURLLoaderFactory (Proxy)"/>
-  <int value="34" label="WorkerMainScriptLoader (No-op)"/>
-  <int value="35" label="WorkerScriptFetcher (No-op)"/>
-  <int value="36" label="WorkerScriptLoader (Proxy)"/>
-</enum>
-
 <enum name="OobeConsumerUpdateScreenSkippedReason">
   <int value="0" label="Critical update was already completed"/>
   <int value="1" label="Update is not required"/>
@@ -62221,15 +60303,6 @@
   <int value="3" label="Accessed Password Details through the long press menu"/>
 </enum>
 
-<enum name="PathValidationReason">
-  <int value="0" label="Reason unknown"/>
-  <int value="1" label="Multi port"/>
-  <int value="2" label="Reverse path validation"/>
-  <int value="3" label="Server preferred address migration"/>
-  <int value="4" label="Port migration"/>
-  <int value="5" label="Connection migration"/>
-</enum>
-
 <enum name="PaymentRequestCheckoutFunnelSteps">
   <int value="0" label="Initiated"/>
   <int value="1" label="Show() called"/>
@@ -63517,11 +61590,6 @@
   <int value="12" label="Online"/>
 </enum>
 
-<enum name="Ports">
-  <int value="80" label="Port 80"/>
-  <int value="443" label="Port 443"/>
-</enum>
-
 <enum name="PowerButtonMenuActionType">
   <int value="0" label="Sign out"/>
   <int value="1" label="Power off"/>
@@ -66723,16 +64791,6 @@
   <int value="9" label="Unknown result"/>
 </enum>
 
-<enum name="ProxyScheme">
-  <int value="1" label="SCHEME_INVALID"/>
-  <int value="2" label="SCHEME_DIRECT"/>
-  <int value="4" label="SCHEME_HTTP"/>
-  <int value="8" label="SCHEME_SOCKS4"/>
-  <int value="16" label="SCHEME_SOCKS5"/>
-  <int value="32" label="SCHEME_HTTPS"/>
-  <int value="64" label="SCHEME_QUIC"/>
-</enum>
-
 <enum name="PSimSetupFlowResult">
   <int value="0" label="SUCCESS"/>
   <int value="1" label="CANCELLED"/>
@@ -66768,21 +64826,6 @@
   </int>
 </enum>
 
-<enum name="PushedStreamVaryResponseHeaderValues">
-  <int value="0" label="There is no Vary header."/>
-  <int value="1" label="The value of Vary is empty."/>
-  <int value="2" label="The value of Vary is &quot;*&quot;."/>
-  <int value="3"
-      label="The value of Vary is &quot;accept-encoding&quot; (case
-             insensitive)."/>
-  <int value="4"
-      label="The value of Vary contains &quot;accept-encoding&quot; (case
-             insensitive) and some other field names as well."/>
-  <int value="5"
-      label="The value of Vary does not contain &quot;accept-encoding&quot;,
-             is not empty, and is not &quot;*&quot;."/>
-</enum>
-
 <enum name="PushEventStatus">
   <int value="0" label="Successful"/>
   <int value="1" label="Message was invalid"/>
@@ -66963,334 +65006,6 @@
   <int value="3" label="Suspend"/>
 </enum>
 
-<enum name="QuicAddressMismatch">
-  <int value="0" label="Address mismatch: IPv4 IPv4"/>
-  <int value="1" label="Address mismatch: IPv6 IPv6"/>
-  <int value="2" label="Address mismatch: IPv4 IPv6"/>
-  <int value="3" label="Address mismatch: IPv6 IPv4"/>
-  <int value="4" label="Port mismatch: IPv4 IPv4"/>
-  <int value="5" label="Port mismatch: IPv6 IPv6"/>
-  <int value="6" label="Address and port match: IPv4 IPv4"/>
-  <int value="7" label="Address and port match: IPv6 IPv6"/>
-</enum>
-
-<enum name="QuicAltSvcFormat">
-  <int value="0" label="Google format"/>
-  <int value="1" label="IETF format"/>
-</enum>
-
-<enum name="QuicBadPacketLossEvents">
-  <int value="1" label="ONE_PACKET_LOST"/>
-  <int value="2" label="TWO_PACKETS_LOST"/>
-  <int value="3" label="THREE_PACKETS_LOST"/>
-  <int value="4" label="FOUR_PACKETS_LOST"/>
-  <int value="5" label="FIVE_PACKETS_LOST"/>
-</enum>
-
-<enum name="QuicConnectionMigrationStatus">
-  <int value="0" label="No stream to migrate"/>
-  <int value="1" label="Already migrated"/>
-  <int value="2" label="Internal error"/>
-  <int value="3" label="Too many migrations"/>
-  <int value="4" label="Success"/>
-  <int value="5" label="Disabled by non-migratable stream"/>
-  <int value="6" label="Migration not enabled"/>
-  <int value="7" label="No alternate network"/>
-  <int value="8" label="Disabled by too many path degradings"/>
-  <int value="9" label="Disabled by config"/>
-  <int value="10" label="Path degrading not enabled"/>
-  <int value="11" label="Timeout with no new network"/>
-  <int value="12"
-      label="Exceeding maximum number of migrations on write error"/>
-  <int value="13" label="Path degrading before handshake confirmed"/>
-  <int value="14" label="Idle migration period exceeded"/>
-  <int value="15" label="Migration fails due to lack of connection ID"/>
-</enum>
-
-<enum name="QuicDisabledReason">
-  <int value="1" label="Public reset post handshake"/>
-  <int value="2" label="Timeout with open streams"/>
-  <int value="3" label="Bad packet loss rate"/>
-</enum>
-
-<enum name="QuicDiskCacheFailureReason">
-  <int value="0" label="WAIT_FOR_DATA_READY_INVALID_ARGUMENT_FAILURE"/>
-  <int value="1" label="GET_BACKEND_FAILURE"/>
-  <int value="2" label="OPEN_FAILURE"/>
-  <int value="3" label="CREATE_OR_OPEN_FAILURE"/>
-  <int value="4" label="PARSE_NO_DATA_FAILURE"/>
-  <int value="5" label="PARSE_FAILURE"/>
-  <int value="6" label="READ_FAILURE"/>
-  <int value="7" label="READY_TO_PERSIST_FAILURE"/>
-  <int value="8" label="PERSIST_NO_BACKEND_FAILURE"/>
-  <int value="9" label="WRITE_FAILURE"/>
-  <int value="10" label="NO_FAILURE"/>
-  <int value="11" label="PARSE_DATA_DECODE_FAILURE"/>
-</enum>
-
-<enum name="QuicDroppedPacketReason">
-  <int value="0" label="INVALID_PUBLIC_HEADER"/>
-  <int value="1" label="VERSION_MISMATCH"/>
-  <int value="2" label="INVALID_VERSION_NEGOTIATION_PACKET"/>
-  <int value="3" label="INVALID_PUBLIC_RESET_PACKET"/>
-  <int value="4" label="INVALID_PACKET_NUMBER"/>
-  <int value="5" label="INVALID_DIVERSIFICATION_NONCE"/>
-  <int value="6" label="DECRYPTION_FAILURE"/>
-</enum>
-
-<enum name="QuicErrorCodes">
-  <int value="0" label="NO_ERROR"/>
-  <int value="1" label="INTERNAL_ERROR"/>
-  <int value="2" label="STREAM_DATA_AFTER_TERMINATION"/>
-  <int value="3" label="INVALID_PACKET_HEADER"/>
-  <int value="4" label="INVALID_FRAME_DATA"/>
-  <int value="5" label="INVALID_FEC_DATA"/>
-  <int value="6" label="INVALID_RST_STREAM_DATA"/>
-  <int value="7" label="INVALID_CONNECTION_CLOSE_DATA"/>
-  <int value="8" label="INVALID_GOAWAY_DATA"/>
-  <int value="9" label="INVALID_ACK_DATA"/>
-  <int value="10" label="INVALID_VERSION_NEGOTIATION_PACKET"/>
-  <int value="11" label="INVALID_PUBLIC_RST_PACKET"/>
-  <int value="12" label="DECRYPTION_FAILURE"/>
-  <int value="13" label="ENCRYPTION_FAILURE"/>
-  <int value="14" label="PACKET_TOO_LARGE"/>
-  <int value="15" label="PACKET_FOR_NONEXISTENT_STREAM"/>
-  <int value="16" label="PEER_GOING_AWAY"/>
-  <int value="17" label="INVALID_STREAM_ID"/>
-  <int value="18" label="TOO_MANY_OPEN_STREAMS"/>
-  <int value="19" label="PUBLIC_RESET"/>
-  <int value="20" label="INVALID_VERSION"/>
-  <int value="21" label="STREAM_RST_BEFORE_HEADERS_DECOMPRESSED"/>
-  <int value="22" label="INVALID_HEADER_ID"/>
-  <int value="23" label="INVALID_NEGOTIATED_VALUE"/>
-  <int value="24" label="DECOMPRESSION_FAILURE"/>
-  <int value="25" label="NETWORK_IDLE_TIMEOUT"/>
-  <int value="26" label="ERROR_MIGRATING_ADDRESS"/>
-  <int value="27" label="PACKET_WRITE_ERROR"/>
-  <int value="28" label="HANDSHAKE_FAILED"/>
-  <int value="29" label="CRYPTO_TAGS_OUT_OF_ORDER"/>
-  <int value="30" label="CRYPTO_TOO_MANY_ENTRIES"/>
-  <int value="31" label="CRYPTO_INVALID_VALUE_LENGTH"/>
-  <int value="32" label="CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE"/>
-  <int value="33" label="INVALID_CRYPTO_MESSAGE_TYPE"/>
-  <int value="34" label="INVALID_CRYPTO_MESSAGE_PARAMETER"/>
-  <int value="35" label="CRYPTO_MESSAGE_PARAMETER_NOT_FOUND"/>
-  <int value="36" label="CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP"/>
-  <int value="37" label="CRYPTO_MESSAGE_INDEX_NOT_FOUND"/>
-  <int value="38" label="CRYPTO_INTERNAL_ERROR"/>
-  <int value="39" label="CRYPTO_VERSION_NOT_SUPPORTED"/>
-  <int value="40" label="CRYPTO_NO_SUPPORT"/>
-  <int value="41" label="CRYPTO_TOO_MANY_REJECTS"/>
-  <int value="42" label="PROOF_INVALID"/>
-  <int value="43" label="CRYPTO_DUPLICATE_TAG"/>
-  <int value="44" label="CRYPTO_ENCRYPTION_LEVEL_INCORRECT"/>
-  <int value="45" label="CRYPTO_SERVER_CONFIG_EXPIRED"/>
-  <int value="46" label="INVALID_STREAM_DATA"/>
-  <int value="47" label="INVALID_CONGESTION_FEEDBACK_DATA"/>
-  <int value="48" label="MISSING_PAYLOAD"/>
-  <int value="49" label="INVALID_PRIORITY"/>
-  <int value="50" label="EMPTY_STREAM_FRAME_NO_FIN"/>
-  <int value="51" label="PACKET_READ_ERROR"/>
-  <int value="52" label="INVALID_CHANNEL_ID_SIGNATURE"/>
-  <int value="53" label="CRYPTO_SYMMETRIC_KEY_SETUP_FAILED"/>
-  <int value="54" label="CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO"/>
-  <int value="55" label="VERSION_NEGOTIATION_MISMATCH"/>
-  <int value="56" label="INVALID_HEADERS_STREAM_DATA"/>
-  <int value="57" label="INVALID_WINDOW_UPDATE_DATA"/>
-  <int value="58" label="INVALID_BLOCKED_DATA"/>
-  <int value="59" label="FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA"/>
-  <int value="60" label="INVALID_STOP_WAITING_DATA"/>
-  <int value="61" label="UNENCRYPTED_STREAM_DATA"/>
-  <int value="62" label="CONNECTION_IP_POOLED"/>
-  <int value="63" label="FLOW_CONTROL_SENT_TOO_MUCH_DATA"/>
-  <int value="64" label="FLOW_CONTROL_INVALID_WINDOW"/>
-  <int value="65" label="CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE"/>
-  <int value="66" label="TOO_MANY_UNFINISHED_STREAMS"/>
-  <int value="67" label="HANDSHAKE_TIMEOUT"/>
-  <int value="68" label="TOO_MANY_OUTSTANDING_SENT_PACKETS"/>
-  <int value="69" label="TOO_MANY_OUTSTANDING_RECEIVED_PACKETS"/>
-  <int value="70" label="CONNECTION_CANCELLED"/>
-  <int value="71" label="BAD_PACKET_LOSS_RATE"/>
-  <int value="72" label="CRYPTO_HANDSHAKE_STATELESS_REJECT"/>
-  <int value="73" label="PUBLIC_RESETS_POST_HANDSHAKE"/>
-  <int value="74" label="TIMEOUTS_WITH_OPEN_STREAMS"/>
-  <int value="75" label="FAILED_TO_SERIALIZE_PACKET"/>
-  <int value="76" label="TOO_MANY_AVAILABLE_STREAMS"/>
-  <int value="77" label="UNENCRYPTED_FEC_DATA"/>
-  <int value="78" label="INVALID_PATH_CLOSE_DATA"/>
-  <int value="79" label="BAD_MULTIPATH_FLAG"/>
-  <int value="80" label="IP_ADDRESS_CHANGED"/>
-  <int value="81" label="CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS"/>
-  <int value="82" label="CONNECTION_MIGRATION_TOO_MANY_CHANGES"/>
-  <int value="83" label="CONNECTION_MIGRATION_NO_NEW_NETWORK"/>
-  <int value="84" label="CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM"/>
-  <int value="85" label="TOO_MANY_RTOS"/>
-  <int value="86" label="ERROR_MIGRATING_PORT"/>
-  <int value="87" label="OVERLAPPING_STREAM_DATA"/>
-  <int value="88" label="ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA"/>
-  <int value="89" label="MAYBE_CORRUPTED_MEMORY"/>
-  <int value="90" label="CRYPTO_CHLO_TOO_LARGE"/>
-  <int value="91" label="MULTIPATH_PATH_DOES_NOT_EXIST"/>
-  <int value="92" label="MULTIPATH_PATH_NOT_ACTIVE"/>
-  <int value="93" label="TOO_MANY_STREAM_DATA_INTERVALS"/>
-  <int value="94" label="UNSUPPORTED_PROOF_DEMAND"/>
-  <int value="95" label="STREAM_SEQUENCER_INVALID_STATE"/>
-  <int value="96" label="TOO_MANY_SESSIONS_ON_SERVER"/>
-  <int value="97" label="HEADERS_STREAM_DATA_DECOMPRESS_FAILURE"/>
-  <int value="98" label="STREAM_LENGTH_OVERFLOW"/>
-  <int value="99" label="CONNECTION_MIGRATION_DISABLED_BY_CONFIG"/>
-  <int value="100" label="CONNECTION_MIGRATION_INTERNAL_ERROR"/>
-  <int value="101" label="INVALID_APPLICATION_CLOSE_DATA"/>
-  <int value="102" label="INVALID_MAX_DATA_FRAME_DATA"/>
-  <int value="103" label="INVALID_MAX_STREAM_DATA_FRAME_DATA"/>
-  <int value="104" label="MAX_STREAMS_DATA"/>
-  <int value="105" label="STREAMS_BLOCKED_DATA"/>
-  <int value="106" label="INVALID_STREAM_BLOCKED_DATA"/>
-  <int value="107" label="INVALID_NEW_CONNECTION_ID_DATA"/>
-  <int value="108" label="INVALID_STOP_SENDING_FRAME_DATA"/>
-  <int value="109" label="INVALID_PATH_CHALLENGE_DATA"/>
-  <int value="110" label="INVALID_PATH_RESPONSE_DATA"/>
-  <int value="111" label="CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED"/>
-  <int value="112" label="INVALID_MESSAGE_DATA"/>
-  <int value="113" label="IETF_QUIC_PROTOCOL_VIOLATION"/>
-  <int value="114" label="INVALID_NEW_TOKEN"/>
-  <int value="115" label="DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM"/>
-  <int value="116" label="TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM"/>
-  <int value="117" label="INVALID_RETIRE_CONNECTION_ID_DATA"/>
-  <int value="118" label="STREAMS_BLOCKED_ERROR"/>
-  <int value="119" label="MAX_STREAMS_ERROR"/>
-  <int value="120" label="HTTP_DECODER_ERROR"/>
-  <int value="121" label="STALE_CONNECTION_CANCELLED"/>
-  <int value="122" label="IETF_GQUIC_ERROR_MISSING"/>
-  <int value="123"
-      label="WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM"/>
-  <int value="124" label="TOO_MANY_BUFFERED_CONTROL_FRAMES"/>
-  <int value="125" label="TRANSPORT_INVALID_CLIENT_INDICATION"/>
-  <int value="126" label="QPACK_DECOMPRESSION_FAILED"/>
-  <int value="127" label="QPACK_ENCODER_STREAM_ERROR"/>
-  <int value="128" label="QPACK_DECODER_STREAM_ERROR"/>
-  <int value="129" label="STREAM_DATA_BEYOND_CLOSE_OFFSET"/>
-  <int value="130" label="STREAM_MULTIPLE_OFFSET"/>
-  <int value="131" label="HTTP_FRAME_TOO_LARGE"/>
-  <int value="132" label="HTTP_FRAME_ERROR"/>
-  <int value="133" label="HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM"/>
-  <int value="134" label="HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM"/>
-  <int value="135" label="HPACK_INDEX_VARINT_ERROR"/>
-  <int value="136" label="HPACK_NAME_LENGTH_VARINT_ERROR"/>
-  <int value="137" label="HPACK_VALUE_LENGTH_VARINT_ERROR"/>
-  <int value="138" label="HPACK_NAME_TOO_LONG"/>
-  <int value="139" label="HPACK_VALUE_TOO_LONG"/>
-  <int value="140" label="HPACK_NAME_HUFFMAN_ERROR"/>
-  <int value="141" label="HPACK_VALUE_HUFFMAN_ERROR"/>
-  <int value="142" label="HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE"/>
-  <int value="143" label="HPACK_INVALID_INDEX"/>
-  <int value="144" label="HPACK_INVALID_NAME_INDEX"/>
-  <int value="145" label="HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED"/>
-  <int value="146"
-      label="HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK"/>
-  <int value="147"
-      label="HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING"/>
-  <int value="148" label="HPACK_TRUNCATED_BLOCK"/>
-  <int value="149" label="HPACK_FRAGMENT_TOO_LONG"/>
-  <int value="150" label="HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT"/>
-  <int value="151" label="HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM"/>
-  <int value="152" label="HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM"/>
-  <int value="153" label="HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM"/>
-  <int value="154" label="HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM"/>
-  <int value="155" label="HTTP_STREAM_WRONG_DIRECTION"/>
-  <int value="156" label="HTTP_CLOSED_CRITICAL_STREAM"/>
-  <int value="157" label="HTTP_MISSING_SETTINGS_FRAME"/>
-  <int value="158" label="HTTP_DUPLICATE_SETTING_IDENTIFIER"/>
-  <int value="159" label="HTTP_INVALID_MAX_PUSH_ID"/>
-  <int value="160" label="HTTP_STREAM_LIMIT_TOO_LOW"/>
-  <int value="161" label="ZERO_RTT_UNRETRANSMITTABLE"/>
-  <int value="162" label="ZERO_RTT_REJECTION_LIMIT_REDUCED"/>
-  <int value="163" label="ZERO_RTT_RESUMPTION_LIMIT_REDUCED"/>
-  <int value="164" label="HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH"/>
-  <int value="165" label="HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH"/>
-  <int value="166" label="HTTP_GOAWAY_INVALID_STREAM_ID"/>
-  <int value="167" label="HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS"/>
-  <int value="168" label="SILENT_IDLE_TIMEOUT"/>
-  <int value="169" label="QUIC_HTTP_RECEIVE_SPDY_SETTING"/>
-  <int value="170" label="QUIC_MISSING_WRITE_KEYS"/>
-  <int value="171" label="QUIC_HTTP_RECEIVE_SPDY_FRAME"/>
-  <int value="172" label="QUIC_KEY_UPDATE_ERROR"/>
-  <int value="173" label="QUIC_AEAD_LIMIT_REACHED"/>
-  <int value="174" label="QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE"/>
-  <int value="175" label="QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG"/>
-  <int value="176" label="QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR"/>
-  <int value="177" label="QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY"/>
-  <int value="178" label="QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC"/>
-  <int value="179"
-      label="QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX"/>
-  <int value="180"
-      label="QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND"/>
-  <int value="181" label="QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC"/>
-  <int value="182" label="QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL"/>
-  <int value="183"
-      label="QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX"/>
-  <int value="184"
-      label="QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND"/>
-  <int value="185"
-      label="QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY"/>
-  <int value="186" label="QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE"/>
-  <int value="187" label="QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT"/>
-  <int value="188" label="QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW"/>
-  <int value="189" label="QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT"/>
-  <int value="190" label="QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT"/>
-  <int value="191" label="QUIC_MAX_AGE_TIMEOUT"/>
-  <int value="192" label="QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER"/>
-  <int value="193" label="QUIC_INVALID_PRIORITY_UPDATE"/>
-  <int value="194" label="QUIC_PEER_PORT_CHANGE_HANDSHAKE_UNCONFIRMED"/>
-  <int value="195" label="QUIC_TLS_BAD_CERTIFICATE"/>
-  <int value="196" label="QUIC_TLS_UNSUPPORTED_CERTIFICATE"/>
-  <int value="197" label="QUIC_TLS_CERTIFICATE_REVOKED"/>
-  <int value="198" label="QUIC_TLS_CERTIFICATE_EXPIRED"/>
-  <int value="199" label="QUIC_TLS_CERTIFICATE_UNKNOWN"/>
-  <int value="200" label="QUIC_TLS_INTERNAL_ERROR"/>
-  <int value="201" label="QUIC_TLS_UNRECOGNIZED_NAME"/>
-  <int value="202" label="QUIC_TLS_CERTIFICATE_REQUIRED"/>
-  <int value="203" label="QUIC_CONNECTION_ID_LIMIT_ERROR"/>
-  <int value="204" label="QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE"/>
-  <int value="205" label="QUIC_HTTP_RECEIVE_SERVER_PUSH"/>
-  <int value="206" label="QUIC_INVALID_CHARACTER_IN_FIELD_VALUE"/>
-</enum>
-
-<enum name="QuicHandshakeFailureReason">
-  <int value="0" label="UNKNOWN"/>
-  <int value="1" label="BLACK_HOLE"/>
-  <int value="2" label="PUBLIC_RESET"/>
-</enum>
-
-<enum name="QuicHandshakeState">
-  <int value="0" label="STARTED"/>
-  <int value="1" label="ENCRYPTION_ESTABLISHED"/>
-  <int value="2" label="HANDSHAKE_CONFIRMED"/>
-  <int value="3" label="FAILED"/>
-</enum>
-
-<enum name="QuicHttp3ErrorCodes">
-  <int value="256" label="H3_NO_ERROR"/>
-  <int value="257" label="H3_GENERAL_PROTOCOL_ERROR"/>
-  <int value="258" label="H3_INTERNAL_ERROR"/>
-  <int value="259" label="H3_STREAM_CREATION_ERROR"/>
-  <int value="260" label="H3_CLOSED_CRITICAL_STREAM"/>
-  <int value="261" label="H3_FRAME_UNEXPECTED"/>
-  <int value="262" label="H3_FRAME_ERROR"/>
-  <int value="263" label="H3_EXCESSIVE_LOAD"/>
-  <int value="264" label="H3_ID_ERROR"/>
-  <int value="265" label="H3_SETTINGS_ERROR"/>
-  <int value="266" label="H3_MISSING_SETTINGS"/>
-  <int value="267" label="H3_REQUEST_REJECTED"/>
-  <int value="268" label="H3_REQUEST_CANCELLED"/>
-  <int value="269" label="H3_REQUEST_INCOMPLETE"/>
-  <int value="271" label="H3_CONNECT_ERROR"/>
-  <int value="272" label="H3_VERSION_FALLBACK"/>
-  <int value="512" label="QPACK_DECOMPRESSION_FAILED"/>
-  <int value="513" label="QPACK_ENCODER_STREAM_ERROR"/>
-  <int value="514" label="QPACK_DECODER_STREAM_ERROR"/>
-</enum>
-
 <enum name="QuickAnswersDictionaryIntentSource">
   <int value="0" label="kTextClassifier"/>
   <int value="1" label="kHunspell"/>
@@ -67351,22 +65066,6 @@
   <int value="13" label="All time deletion time range selected"/>
 </enum>
 
-<enum name="QuicKeyUpdateReason">
-  <int value="0" label="kInvalid"/>
-  <int value="1" label="kRemote"/>
-  <int value="2" label="kLocalForTests"/>
-  <int value="3" label="kLocalForInteropRunner"/>
-  <int value="4" label="kLocalAeadConfidentialityLimit"/>
-  <int value="5" label="kLocalKeyUpdateLimitOverride"/>
-</enum>
-
-<enum name="QuicKeyUpdateSuccess">
-  <int value="0" label="kInvalid"/>
-  <int value="1" label="kSuccess"/>
-  <int value="2" label="kFailedInitial"/>
-  <int value="3" label="kFailedNonInitial"/>
-</enum>
-
 <enum name="QuickofficeErrorTypes">
   <int value="0" label="doc uncaught js exception"/>
   <int value="1" label="docx uncaught js exception"/>
@@ -67567,137 +65266,6 @@
   <int value="10" label="Wifi hide status not found"/>
 </enum>
 
-<enum name="QuicNotReusableReason">
-  <int value="0" label="NULLPTR"/>
-  <int value="1" label="TOO_SMALL"/>
-  <int value="2" label="REF_COUNT"/>
-</enum>
-
-<enum name="QuicPlatformNotification">
-  <int value="0" label="NETWORK_CONNECTED"/>
-  <int value="1" label="NETWORK_MADE_DEFAULT"/>
-  <int value="2" label="NETWORK_DISCONNECTED"/>
-  <int value="3" label="NETWORK_SOON_TO_DISCONNECT"/>
-  <int value="4" label="NETWORK_IP_ADDRESS_CHANGED"/>
-</enum>
-
-<enum name="QuicProtocolErrorRetryStatus">
-  <int value="0" label="NoRetryExceededMaxRetries"/>
-  <int value="1" label="NoRetryHeaderReceived"/>
-  <int value="2" label="NoRetryNoAlternativeService"/>
-  <int value="3" label="RetryAltServiceBroken"/>
-  <int value="4" label="RetryAltServiceNotBroken"/>
-</enum>
-
-<enum name="QuicRstStreamErrorCodes">
-  <int value="0" label="NO_ERROR"/>
-  <int value="1" label="ERROR_PROCESSING_STREAM"/>
-  <int value="2" label="MULTIPLE_TERMINATION_OFFSETS"/>
-  <int value="3" label="BAD_APPLICATION_PAYLOAD"/>
-  <int value="4" label="CONNECTION_ERROR"/>
-  <int value="5" label="PEER_GOING_AWAY"/>
-  <int value="6" label="CANCELLED"/>
-  <int value="7" label="RST_ACKNOWLEDGEMENT"/>
-  <int value="8" label="REFUSED"/>
-  <int value="9" label="INVALID_PROMISE_URL"/>
-  <int value="10" label="UNAUTHORIZED_PROMISE_URL"/>
-  <int value="11" label="DUPLICATE_PROMISE_URL"/>
-  <int value="12" label="PROMISE_VARY_MISMATCH"/>
-  <int value="13" label="INVALID_PROMISE_METHOD"/>
-  <int value="14" label="PUSH_STREAM_TIMED_OUT"/>
-  <int value="15" label="HEADERS_TOO_LARGE"/>
-  <int value="16" label="TTL_EXPIRED"/>
-  <int value="17" label="DATA_AFTER_CLOSE_OFFSET"/>
-  <int value="18" label="GENERAL_PROTOCOL_ERROR"/>
-  <int value="19" label="INTERNAL_ERROR"/>
-  <int value="20" label="CREATION_ERROR"/>
-  <int value="21" label="CLOSED_CRITICAL_STREAM"/>
-  <int value="22" label="FRAME_UNEXPECTED"/>
-  <int value="23" label="FRAME_ERROR"/>
-  <int value="24" label="EXCESSIVE_LOAD"/>
-  <int value="25" label="ID_ERROR"/>
-  <int value="26" label="SETTINGS_ERROR"/>
-  <int value="27" label="MISSING_SETTINGS"/>
-  <int value="28" label="REQUEST_REJECTED"/>
-  <int value="29" label="REQUEST_INCOMPLETE"/>
-  <int value="30" label="CONNECT_ERROR"/>
-  <int value="31" label="VERSION_FALLBACK"/>
-  <int value="32" label="DECOMPRESSION_FAILED"/>
-  <int value="33" label="ENCODER_STREAM_ERROR"/>
-  <int value="34" label="DECODER_STREAM_ERROR"/>
-  <int value="35" label="UNKNOWN_APPLICATION_ERROR_CODE"/>
-</enum>
-
-<enum name="QuicServerConfigState">
-  <int value="0" label="SERVER_CONFIG_EMPTY"/>
-  <int value="1" label="SERVER_CONFIG_INVALID"/>
-  <int value="2" label="SERVER_CONFIG_CORRUPTED"/>
-  <int value="3" label="SERVER_CONFIG_EXPIRED"/>
-  <int value="4" label="SERVER_CONFIG_INVALID_EXPIRY"/>
-  <int value="5" label="SERVER_CONFIG_VALID"/>
-</enum>
-
-<enum name="QuicSessionErrorCodes">
-  <int value="0" label="CONNECTING_SOCKET"/>
-  <int value="1" label="SETTING_RECEIVE_BUFFER"/>
-  <int value="2" label="SETTING_SEND_BUFFER"/>
-  <int value="3" label="SETTING_DO_NOT_FRAGMENT"/>
-</enum>
-
-<enum name="QuicTransportErrorCodes">
-  <int value="0" label="NO_ERROR"/>
-  <int value="1" label="INTERNAL_ERROR"/>
-  <int value="2" label="SERVER_BUSY"/>
-  <int value="3" label="FLOW_CONTROL_ERROR"/>
-  <int value="4" label="STREAM_LIMIT_ERROR"/>
-  <int value="5" label="STREAM_STATE_ERROR"/>
-  <int value="6" label="FINAL_SIZE_ERROR"/>
-  <int value="7" label="FRAME_ENCODING_ERROR"/>
-  <int value="8" label="TRANSPORT_PARAMETER_ERROR"/>
-  <int value="9" label="CONNECTION_ID_LIMIT_ERROR"/>
-  <int value="10" label="PROTOCOL_VIOLATION"/>
-  <int value="11" label="INVALID_TOKEN"/>
-  <int value="12" label="APPLICATION_ERROR"/>
-  <int value="13" label="CRYPTO_BUFFER_EXCEEDED"/>
-  <int value="14" label="KEY_UPDATE_ERROR"/>
-  <int value="256" label="CRYPTO_ERROR_close_notify"/>
-  <int value="266" label="CRYPTO_ERROR_unexpected_message"/>
-  <int value="276" label="CRYPTO_ERROR_bad_record_mac"/>
-  <int value="278" label="CRYPTO_ERROR_record_overflow"/>
-  <int value="296" label="CRYPTO_ERROR_handshake_failure"/>
-  <int value="298" label="CRYPTO_ERROR_bad_certificate"/>
-  <int value="299" label="CRYPTO_ERROR_unsupported_certificate"/>
-  <int value="300" label="CRYPTO_ERROR_certificate_revoked"/>
-  <int value="301" label="CRYPTO_ERROR_certificate_expired"/>
-  <int value="302" label="CRYPTO_ERROR_certificate_unknown"/>
-  <int value="303" label="CRYPTO_ERROR_illegal_parameter"/>
-  <int value="304" label="CRYPTO_ERROR_unknown_ca"/>
-  <int value="305" label="CRYPTO_ERROR_access_denied"/>
-  <int value="306" label="CRYPTO_ERROR_decode_error"/>
-  <int value="307" label="CRYPTO_ERROR_decrypt_error"/>
-  <int value="326" label="CRYPTO_ERROR_protocol_version"/>
-  <int value="327" label="CRYPTO_ERROR_insufficient_security"/>
-  <int value="336" label="CRYPTO_ERROR_internal_error"/>
-  <int value="342" label="CRYPTO_ERROR_inappropriate_fallback"/>
-  <int value="346" label="CRYPTO_ERROR_user_canceled"/>
-  <int value="365" label="CRYPTO_ERROR_missing_extension"/>
-  <int value="366" label="CRYPTO_ERROR_unsupported_extension"/>
-  <int value="368" label="CRYPTO_ERROR_unrecognized_name"/>
-  <int value="369" label="CRYPTO_ERROR_bad_certificate_status_response"/>
-  <int value="371" label="CRYPTO_ERROR_unknown_psk_identity"/>
-  <int value="372" label="CRYPTO_ERROR_certificate_required"/>
-  <int value="376" label="CRYPTO_ERROR_no_application_protocol"/>
-</enum>
-
-<enum name="QuicWriteStatus">
-  <int value="0" label="WRITE_STATUS_OK"/>
-  <int value="1" label="WRITE_STATUS_BLOCKED"/>
-  <int value="3" label="WRITE_STATUS_BLOCKED_DATA_BUFFERED"/>
-  <int value="4" label="WRITE_STATUS_ERROR"/>
-  <int value="5" label="WRITE_STATUS_MSG_TOO_BIG"/>
-  <int value="6" label="WRITE_STATUS_FAILED_TO_COALESCE_PACKET"/>
-</enum>
-
 <enum name="QuotaDatabaseDisabledReason">
   <int value="0" label="The first step of bootstrapping failed"/>
   <int value="1" label="The second step of bootstrapping failed"/>
@@ -69062,15 +66630,6 @@
   <int value="13" label="Rejected due to fenced frame"/>
 </enum>
 
-<enum name="ResolutionCategory">
-  <int value="0" label="RESOLVE_SUCCESS"/>
-  <int value="1" label="RESOLVE_FAIL"/>
-  <int value="2" label="RESOLVE_SPECULATIVE_SUCCESS"/>
-  <int value="3" label="RESOLVE_SPECULATIVE_FAIL"/>
-  <int value="4" label="RESOLVE_ABORT"/>
-  <int value="5" label="RESOLVE_SPECULATIVE_ABORT"/>
-</enum>
-
 <enum name="ResourceExhaustedCase">
   <int value="0" label="No disk space left for data"/>
   <int value="1" label="No disk space left for metadata"/>
@@ -69207,17 +66766,6 @@
   <int value="2" label="Stage 2 Failure"/>
 </enum>
 
-<enum name="RSAKeyUsage">
-  <int value="0" label="Not an RSA key"/>
-  <int value="1" label="OK (no extension)"/>
-  <int value="2" label="OK (both bits present)"/>
-  <int value="3" label="OK (digitalSignature present)"/>
-  <int value="4" label="OK (keyEncipherment present)"/>
-  <int value="5" label="Missing digitalSignature"/>
-  <int value="6" label="Missing keyEncipherment"/>
-  <int value="7" label="Error parsing certificate"/>
-</enum>
-
 <enum name="RulesetVerificationStatus">
   <int value="0" label="Not verified"/>
   <int value="1" label="Intact"/>
@@ -69985,21 +67533,6 @@
   <int value="7" label="SCT suffix not found"/>
 </enum>
 
-<enum name="SCTOrigin">
-  <int value="0" label="SCT_EMBEDDED"/>
-  <int value="1" label="SCT_FROM_TLS_EXTENSION"/>
-  <int value="2" label="SCT_FROM_OCSP_RESPONSE"/>
-</enum>
-
-<enum name="SCTVerifyStatus">
-  <int value="0" label="SCT_STATUS_NONE"/>
-  <int value="1" label="SCT_STATUS_LOG_UNKNOWN"/>
-  <int value="2" label="DEPRECATED: SCT_STATUS_INVALID"/>
-  <int value="3" label="SCT_STATUS_OK"/>
-  <int value="4" label="SCT_STATUS_INVALID_SIGNATURE"/>
-  <int value="5" label="SCT_STATUS_INVALID_TIMESTAMP"/>
-</enum>
-
 <enum name="SearchAnswerRequestResult">
   <int value="0" label="Another Request Started"/>
   <int value="1" label="Failed"/>
@@ -70165,17 +67698,6 @@
              'Secure' directive (app targets &gt;= Android R)"/>
 </enum>
 
-<enum name="SecureDnsModeDetails">
-  <int value="0" label="Off, by user choice"/>
-  <int value="1" label="Off, by enterprise policy"/>
-  <int value="2" label="Off, due to managed environment"/>
-  <int value="3" label="Off, due to parental controls"/>
-  <int value="4" label="Automatic, by user choice"/>
-  <int value="5" label="Automatic, by enterprise policy"/>
-  <int value="6" label="Secure, by user choice"/>
-  <int value="7" label="Secure, by enterprise policy"/>
-</enum>
-
 <enum name="SecurePaymentConfirmationAuthenticationDialogResult">
   <int value="0" label="Canceled"/>
   <int value="1" label="Accepted"/>
@@ -71204,19 +68726,6 @@
   <int value="2" label="Shared Zstd"/>
 </enum>
 
-<enum name="SharedDictionaryStoreError">
-  <int value="0" label="Ok"/>
-  <int value="1" label="FailedToInitializeDatabase"/>
-  <int value="2" label="InvalidSql"/>
-  <int value="3" label="FailedToExecuteSql"/>
-  <int value="4" label="FailedToBeginTransaction"/>
-  <int value="5" label="FailedToCommitTransaction"/>
-  <int value="6" label="InvalidTotalDictSize"/>
-  <int value="7" label="FailedToGetTotalDictSize"/>
-  <int value="8" label="FailedToSetTotalDictSize"/>
-  <int value="9" label="TooBigDictionary"/>
-</enum>
-
 <enum name="SharedImageBackingType">
   <summary>Corresponds to SharedImageBacking implementations.</summary>
   <int value="0" label="TestImageBacking"/>
@@ -72748,136 +70257,6 @@
   <int value="4" label="Tab Destroyed"/>
 </enum>
 
-<enum name="SpdyFrameFlowControlState">
-  <int value="0" label="Send not stalled"/>
-  <int value="1" label="Send stalled by stream"/>
-  <int value="2" label="Send stalled by session"/>
-  <int value="3" label="Send stalled by stream and session"/>
-</enum>
-
-<enum name="SpdyIPPoolDomainMatch">
-  <int value="0" label="mismatch"/>
-  <int value="1" label="match"/>
-</enum>
-
-<enum name="SpdyProtocolErrorDetails2">
-<!-- SpdyFramer::SpdyErrors -->
-
-  <int value="0" label="No error"/>
-  <int value="1" label="Invalid Control Frame"/>
-  <int value="2" label="Control Frame Payload Too Large"/>
-  <int value="3" label="Zlib Init Failure"/>
-  <int value="4" label="Unsupported Version"/>
-  <int value="5" label="Decompress Failure"/>
-  <int value="6" label="Compress Failure"/>
-  <int value="7" label="Credential Frame Corrupt"/>
-  <int value="8" label="Invalid Data Frame Flags"/>
-  <int value="9" label="Invalid Control Frame Flags"/>
-<!-- SpdyRstStreamStatus -->
-
-  <int value="10" label="(Unused)"/>
-  <int value="11" label="Protocol Error"/>
-  <int value="12" label="Closed Stream"/>
-  <int value="13" label="Refused Stream"/>
-  <int value="14" label="Unsupported Version (SpdyRstStreamStatus)"/>
-  <int value="15" label="Cancel"/>
-  <int value="16" label="Internal Error"/>
-  <int value="17" label="Flow Control Error"/>
-  <int value="18" label="Stream In Use"/>
-  <int value="19" label="Stream Already Closed"/>
-  <int value="20" label="Invalid Credentials"/>
-  <int value="21" label="Frame Too Large"/>
-<!-- SpdySession errors -->
-
-  <int value="22" label="Unexpected Ping"/>
-  <int value="23" label="Rst Stream For Non Active Stream"/>
-  <int value="24" label="Spdy Compression Failure"/>
-  <int value="25" label="Request For Secure Content Over Insecure Session"/>
-  <int value="26" label="Syn Reply Not Received"/>
-  <int value="27" label="Invalid Window Update Size"/>
-  <int value="28" label="Receive Window Size Violation"/>
-<!-- More SpdyFramer::SpdyErrors -->
-
-  <int value="29" label="GoAway Frame Corrupt"/>
-  <int value="30" label="RstStream Frame Corrupt"/>
-  <int value="31" label="Unexpected Frame (Expected Continuation)"/>
-<!-- More SpdyRstStreamStatus -->
-
-  <int value="32" label="Timeout waiting for settings acknowledgement"/>
-  <int value="33"
-      label="Connection established in response to CONNECT request was
-             abnormally closed"/>
-  <int value="34" label="Peer exhibiting suspect behavior."/>
-  <int value="35" label="Inadequate security."/>
-  <int value="36" label="HTTP/1.1 required."/>
-<!-- More SpdyFramer::SpdyErrors -->
-
-  <int value="37" label="Invalid control frame size."/>
-  <int value="38" label="Invalid stream ID."/>
-  <int value="39" label="Invalid padding length."/>
-  <int value="40" label="Oversized payload."/>
-<!-- More SpdyRstStreamStatus -->
-
-  <int value="41" label="No error."/>
-  <int value="42" label="Compression error."/>
-<!-- HttpDecoder or HttpDecoderAdapter errors -->
-
-  <int value="43" label="Varint beyond implementation limit."/>
-  <int value="44" label="Name length varint error."/>
-  <int value="45" label="Value legnth varint error."/>
-  <int value="46" label="Name string literal length exceeds buffer limit."/>
-  <int value="47" label="Value string literal length exceeds buffer limit."/>
-  <int value="48" label="Error in Huffman encoding for name."/>
-  <int value="49" label="Error in Huffman encoding for value."/>
-  <int value="50"
-      label="Next instruction should have been a dynamic table size update."/>
-  <int value="51"
-      label="Invalid index in indexed header field representation."/>
-  <int value="52"
-      label="Invalid index in literal header field with indexed name
-             representation."/>
-  <int value="53" label="Dynamic table size update not allowed."/>
-  <int value="54"
-      label="Initial dynamic table size update is above low water mark."/>
-  <int value="55"
-      label="Dynamic table size update is above acknowledged setting."/>
-  <int value="56" label="HPACK block ends in the middle of an instruction."/>
-  <int value="57" label="Incoming data fragment exceeds buffer limit."/>
-  <int value="58" label="Total compressed HPACK data size exceeds limit."/>
-</enum>
-
-<enum name="SpdyPushedStreamFate">
-  <int value="0" label="TOO_MANY_PUSHED_STREAMS"/>
-  <int value="1" label="TIMEOUT"/>
-  <int value="2" label="PROMISED_STREAM_ID_PARITY_ERROR"/>
-  <int value="3" label="ASSOCIATED_STREAM_ID_PARITY_ERROR"/>
-  <int value="4" label="STREAM_ID_OUT_OF_ORDER"/>
-  <int value="5" label="GOING_AWAY"/>
-  <int value="6" label="INVALID_URL"/>
-  <int value="7" label="INACTIVE_ASSOCIATED_STREAM"/>
-  <int value="8" label="NON_HTTP_SCHEME_FROM_TRUSTED_PROXY"/>
-  <int value="9" label="NON_HTTPS_PUSHED_SCHEME"/>
-  <int value="10" label="NON_HTTPS_ASSOCIATED_SCHEME"/>
-  <int value="11" label="CERTIFICATE_MISMATCH"/>
-  <int value="12" label="DUPLICATE_URL"/>
-  <int value="13" label="CLIENT_REQUEST_NOT_RANGE"/>
-  <int value="14" label="PUSHED_REQUEST_NOT_RANGE"/>
-  <int value="15" label="RANGE_MISMATCH"/>
-  <int value="16" label="VARY_MISMATCH"/>
-  <int value="17" label="ACCEPTED_NO_VARY"/>
-  <int value="18" label="ACCEPTED_MATCHING_VARY"/>
-  <int value="19" label="PUSH_DISABLED"/>
-  <int value="20" label="ALREADY_IN_CACHE"/>
-  <int value="21" label="UNSUPPORTED_STATUS_CODE"/>
-</enum>
-
-<enum name="SpdySessionGet">
-  <int value="0" label="created new"/>
-  <int value="1" label="found existing"/>
-  <int value="2" label="found existing from IP Pool"/>
-  <int value="3" label="imported from socket"/>
-</enum>
-
 <enum name="SpecialLocalePromoAction">
   <int value="0" label="Use Sogou"/>
   <int value="1" label="Keep Google"/>
@@ -73217,19 +70596,6 @@
   <int value="52393" label="TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"/>
 </enum>
 
-<enum name="SSLECHResult">
-  <summary>The result of a TLS connection that offered ECH</summary>
-  <int value="0" label="The connection succeeded on the initial connection"/>
-  <int value="1"
-      label="The connection failed on the initial connection, without
-             providing retry configs"/>
-  <int value="2" label="The connection succeeded after getting retry configs"/>
-  <int value="3" label="The connection failed after getting retry configs"/>
-  <int value="4"
-      label="The connection succeeded after getting a rollback signal"/>
-  <int value="5" label="The connection failed after getting a rollback signal"/>
-</enum>
-
 <enum name="SSLErrorCauses">
   <int value="0" label="CLOCK_PAST: System clock set early">
     This cause is recorded if the SSL error is CERT_DATE_INVALID and Chrome had
@@ -73367,93 +70733,6 @@
   <int value="16" label="CERT_SYMANTEC_LEGACY"/>
 </enum>
 
-<enum name="SSLHandshakeDetails">
-  <int value="0" label="TLS 1.2 (or earlier) full handshake (2-RTT)"/>
-  <int value="1" label="TLS 1.2 (or earlier) resumption (1-RTT)"/>
-  <int value="2" label="TLS 1.2 full handshake with False Start (1-RTT)"/>
-  <int value="3"
-      label="TLS 1.3 full handshake, HelloRetryRequest unknown (1-RTT or
-             2-RTT)"/>
-  <int value="4"
-      label="TLS 1.3 resumption handshake, HelloRetryRequest unknown (1-RTT
-             or 2-RTT)"/>
-  <int value="5" label="TLS 1.3 0-RTT handshake (0-RTT)"/>
-  <int value="6" label="TLS 1.3 full handshake (1-RTT)"/>
-  <int value="7" label="TLS 1.3 resumption handshake (1-RTT)"/>
-  <int value="8" label="TLS 1.3 full handshake with HelloRetryRequest (2-RTT)"/>
-  <int value="9"
-      label="TLS 1.3 resumption handshake with HelloRetryRequest (2-RTT)"/>
-</enum>
-
-<enum name="SSLHandshakeEarlyDataReason">
-<!-- Corresponds to //third_party/boringssl's ssl_early_data_reason_t -->
-
-  <int value="0"
-      label="The handshake has not progressed far enough for the 0-RTT status
-             to be known."/>
-  <int value="1" label="0-RTT is disabled for this connection."/>
-  <int value="2" label="0-RTT was accepted."/>
-  <int value="3"
-      label="The negotiated protocol version does not support 0-RTT."/>
-  <int value="4"
-      label="The peer declined to offer or accept 0-RTT for an unknown
-             reason."/>
-  <int value="5" label="The client did not offer a session."/>
-  <int value="6" label="The server declined to resume the session."/>
-  <int value="7" label="The session does not support 0-RTT."/>
-  <int value="8" label="The server sent a HelloRetryRequest."/>
-  <int value="9"
-      label="The negotiated ALPN protocol did not match the session."/>
-  <int value="10"
-      label="The connection negotiated Channel ID, which is incompatible with
-             0-RTT."/>
-  <int value="11"
-      label="The connection negotiated token binding, which is incompatible
-             with 0-RTT."/>
-  <int value="12" label="The client and server ticket age were too far apart."/>
-  <int value="13"
-      label="QUIC parameters differ between this connection and the original."/>
-</enum>
-
-<enum name="SSLKeyLogFileAction">
-  <int value="0" label="SSLKeyLogger enabled"/>
-  <int value="1" label="ssl-key-log-file switch set"/>
-  <int value="2" label="SSLKEYLOGFILE environment variable set"/>
-</enum>
-
-<enum name="SSLLegacyCryptoFallback">
-  <int value="0" label="No fallback used"/>
-  <int value="1" label="Used fallback and negotiated 3DES"/>
-  <int value="2" label="Used fallback and negotiated SHA-1"/>
-  <int value="3"
-      label="Used fallback and sent a certificate signed with
-             RSASSA-PKCS1-v1_5-SHA-1"/>
-  <int value="4"
-      label="Used fallback, negotiated 3DES, and sent a certificate signed
-             with RSASSA-PKCS1-v1_5-SHA-1"/>
-  <int value="5"
-      label="Used fallback, negotiated SHA-1, and sent a certificate signed
-             with RSASSA-PKCS1-v1_5-SHA-1"/>
-  <int value="6" label="Used fallback for unknown reason"/>
-</enum>
-
-<enum name="SSLNegotiatedAlpnProtocol">
-  <int value="0" label="ALPN not used"/>
-  <int value="1" label="HTTP/1.1 negotiated via ALPN"/>
-  <int value="2" label="HTTP/2 negotiated via ALPN"/>
-</enum>
-
-<enum name="SSLOrQUICVersion">
-  <int value="0" label="Unknown"/>
-  <int value="1" label="SSL 2.0"/>
-  <int value="2" label="SSL 3.0"/>
-  <int value="3" label="TLS 1.0"/>
-  <int value="4" label="TLS 1.1"/>
-  <int value="5" label="TLS 1.2"/>
-  <int value="6" label="TLS 1.3"/>
-  <int value="7" label="QUIC"/>
-</enum>
-
 <enum name="SSLSignatureAlgorithm">
   <int value="513" label="rsa_pkcs1_sha1"/>
   <int value="515" label="ecdsa_sha1"/>
@@ -76073,24 +73352,11 @@
   <int value="2051" label="TPM_E_DEFEND_LOCK_RUNNING"/>
 </enum>
 
-<enum name="TPMSupport">
-  <int value="0" label="None"/>
-  <int value="1" label="RSA"/>
-  <int value="2" label="ECDSA"/>
-</enum>
-
 <enum name="TPMTakeOwnershipResult">
   <int value="0" label="TPM Take Ownership Success"/>
   <int value="1" label="TPM Take Ownership Failed"/>
 </enum>
 
-<enum name="TPMType">
-  <int value="0" label="None"/>
-  <int value="1" label="HW"/>
-  <int value="2" label="Virtual"/>
-  <int value="3" label="Both"/>
-</enum>
-
 <enum name="TPMVersionFingerprint">
 <!--
 Full version information for the fingerprint enum values:
@@ -76902,18 +74168,6 @@
   <int value="21" label="Password Protection UI"/>
 </enum>
 
-<enum name="TrustTokenRequestHelperFactoryOutcome">
-  <int value="0" label="Successfully created an issuance helper"/>
-  <int value="1" label="Successfully created a redemption helper"/>
-  <int value="2" label="Successfully created a signing helper"/>
-  <int value="3" label="Empty 'issuers' parameter"/>
-  <int value="4" label="Unsuitable issuer in 'issuers' parameter"/>
-  <int value="5" label="Unsuitable top frame origin"/>
-  <int value="6"
-      label="Request rejected due to bearing an internal Trust Tokens header"/>
-  <int value="7" label="Rejected by authorizer (check cookie settings?)"/>
-</enum>
-
 <enum name="TypedNavigationUpgradeThrottleEvent">
   <int value="1" label="Started the load of an upgraded HTTPS URL."/>
   <int value="2" label="Successfully finished loading the upgraded HTTPS URL."/>
@@ -77016,16 +74270,6 @@
   <int value="3" label="Occluding and Non-Occluding Damages"/>
 </enum>
 
-<enum name="UnexportableKeyServiceResult">
-  <int value="0" label="Success"/>
-  <int value="1" label="Crypto API failed"/>
-  <int value="2" label="Key not found"/>
-  <int value="3" label="Key collision"/>
-  <int value="4" label="No key provider"/>
-  <int value="5" label="Algorithm not supported"/>
-  <int value="6" label="Key not ready"/>
-</enum>
-
 <enum name="UnifiedConsentSyncDataTypesOffAfterAdvancedOptIn">
   <int value="0" label="None"/>
   <int value="1" label="Apps"/>
@@ -77130,12 +74374,6 @@
   <int value="14" label="I/O device error."/>
 </enum>
 
-<enum name="UnsolicitedHttpsRecordStatus">
-  <int value="0" label="Malformed"/>
-  <int value="1" label="Alias"/>
-  <int value="2" label="Service"/>
-</enum>
-
 <enum name="UpdateAppBadgeTypes">
   <int value="0" label="Set numeric badge"/>
   <int value="1" label="Set flag badge"/>
@@ -77409,18 +74647,6 @@
   <int value="2" label="Scope"/>
 </enum>
 
-<enum name="URLRequestReferrerPolicy">
-  <int value="0" label="CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE"/>
-  <int value="1"
-      label="REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN"/>
-  <int value="2" label="ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN"/>
-  <int value="3" label="NEVER_CLEAR_REFERRER"/>
-  <int value="4" label="ORIGIN"/>
-  <int value="5" label="CLEAR_REFERRER_ON_TRANSITION_CROSS_ORIGIN"/>
-  <int value="6" label="ORIGIN_CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE"/>
-  <int value="7" label="NO_REFERRER"/>
-</enum>
-
 <enum name="UsageStatsEvents">
   <int value="0" label="Opt In"/>
   <int value="1" label="Opt Out"/>
@@ -79776,96 +77002,6 @@
   <int value="11" label="Delete all site entries for a FPS owner"/>
 </enum>
 
-<enum name="WebSocketFallbackResult">
-  <int value="0" label="Success over HTTP/1.1"/>
-  <int value="1" label="Success over HTTP/2"/>
-  <int value="2" label="Success over HTTP/1.1 after fallback"/>
-  <int value="3" label="Failure without fallback"/>
-  <int value="4" label="Failure after fallback"/>
-</enum>
-
-<enum name="WebSocketHandshakeResult2">
-  <int value="0" label="INCOMPLETE">
-    Handshake not completed via Upgrade over HTTP/1 connection.
-  </int>
-  <int value="1" label="INVALID_STATUS">
-    Server responded to Upgrade request with invalid status.
-  </int>
-  <int value="2" label="EMPTY_RESPONSE">
-    Server responded to Upgrade request with empty response.
-  </int>
-  <int value="3" label="FAILED_SWITCHING_PROTOCOLS">
-    Server responded to Upgrade request with 101 status but there was some other
-    network error.
-  </int>
-  <int value="4" label="FAILED_UPGRADE">
-    Server responded to Upgrade request with invalid Upgrade header.
-  </int>
-  <int value="5" label="FAILED_ACCEPT">
-    Server responded to Upgrade request with invalid Sec-WebSocket-Accept
-    header.
-  </int>
-  <int value="6" label="FAILED_CONNECTION">
-    Server responded to Upgrade request with invalid Connection header.
-  </int>
-  <int value="7" label="FAILED_SUBPROTO">
-    Server responded to Upgrade request with invalid Sec-WebSocket-Protocol
-    header.
-  </int>
-  <int value="8" label="FAILED_EXTENSIONS">
-    Server responded to Upgrade request with invalid Sec-WebSocket-Extensions
-    header.
-  </int>
-  <int value="9" label="FAILED">
-    Upgrade request failed due to other network error.
-  </int>
-  <int value="10" label="CONNECTED">
-    Connected via Upgrade over HTTP/1 connection.
-  </int>
-  <int value="11" label="HTTP2_INCOMPLETE">
-    Handshake not completed over an HTTP/2 connection.
-  </int>
-  <int value="12" label="HTTP2_FAILED_STATUS">
-    Server responded to WebSocket request over an HTTP/2 connection with invalid
-    status code.
-  </int>
-  <int value="13" label="HTTP2_FAILED_SUBPROTO">
-    Server responded to WebSocket request over an HTTP/2 connection with invalid
-    sec-websocket-protocol header.
-  </int>
-  <int value="14" label="HTTP2_FAILED_EXTENSIONS">
-    Server responded to WebSocket request over an HTTP/2 connection with invalid
-    sec-websocket-extensions header.
-  </int>
-  <int value="15" label="HTTP2_FAILED">
-    WebSocket request over an HTTP/2 connection failed with some other error.
-  </int>
-  <int value="16" label="HTTP2_CONNECTED">
-    Connected over an HTTP/2 connection.
-  </int>
-  <int value="17" label="HTTP3_INCOMPLETE">
-    Handshake not completed over an HTTP/3 connection.
-  </int>
-  <int value="18" label="HTTP3_FAILED_STATUS">
-    Server responded to WebSocket request over an HTTP/3 connection with invalid
-    status code.
-  </int>
-  <int value="19" label="HTTP3_FAILED_SUBPROTO">
-    Server responded to WebSocket request over an HTTP/3 connection with invalid
-    sec-websocket-protocol header.
-  </int>
-  <int value="20" label="HTTP3_FAILED_EXTENSIONS">
-    Server responded to WebSocket request over an HTTP/3 connection with invalid
-    sec-websocket-extensions header.
-  </int>
-  <int value="21" label="HTTP3_FAILED">
-    WebSocket request over an HTTP/3 connection failed with some other error.
-  </int>
-  <int value="22" label="HTTP3_CONNECTED">
-    Connected over an HTTP/3 connection.
-  </int>
-</enum>
-
 <enum name="WebSocketSendType">
   <int value="0" label="String"/>
   <int value="1" label="ArrayBuffer"/>
@@ -82958,6 +80094,8 @@
   <int value="81" label="Show search companion"/>
   <int value="82" label="Show bookmark side panel"/>
   <int value="83" label="Show performance settings"/>
+  <int value="84" label="Show history cluster side panel"/>
+  <int value="85" label="Show reading mode side panel"/>
 </enum>
 
 <enum name="XHRPageDismissalState">
@@ -82987,153 +80125,12 @@
   <int value="1" label="Error"/>
 </enum>
 
-<enum name="ZeroRttState">
-  <int value="0" label="Attempted and succeeded"/>
-  <int value="1" label="Attempted and rejected"/>
-  <int value="2" label="Not Attempted"/>
-</enum>
-
 <enum name="ZipFileCreator.Result">
   <int value="0" label="Success"/>
   <int value="1" label="Cancelled"/>
   <int value="2" label="Error"/>
 </enum>
 
-<enum name="ZstdFilterDecodingStatus">
-  <int value="0" label="In progress"/>
-  <int value="1" label="End of Frame"/>
-  <int value="2" label="Error"/>
-</enum>
-
-<enum name="ZstdFilterErrorCode">
-  <int value="0" label="No error detected"/>
-  <int value="1" label="Error (generic)"/>
-  <int value="2" label="Reserved (2)"/>
-  <int value="3" label="Reserved (3)"/>
-  <int value="4" label="Reserved (4)"/>
-  <int value="5" label="Reserved (5)"/>
-  <int value="6" label="Reserved (6)"/>
-  <int value="7" label="Reserved (7)"/>
-  <int value="8" label="Reserved (8)"/>
-  <int value="9" label="Reserved (9)"/>
-  <int value="10" label="Unknown frame descriptor"/>
-  <int value="11" label="Reserved (11)"/>
-  <int value="12" label="Version not supported"/>
-  <int value="13" label="Reserved (13)"/>
-  <int value="14" label="Unsupported frame parameter"/>
-  <int value="15" label="Reserved (15)"/>
-  <int value="16" label="Frame requires too much memory for decoding"/>
-  <int value="17" label="Reserved (17)"/>
-  <int value="18" label="Reserved (18)"/>
-  <int value="19" label="Reserved (19)"/>
-  <int value="20" label="Data corruption detected"/>
-  <int value="21" label="Reserved (21)"/>
-  <int value="22" label="Restored data doesn't match checksum"/>
-  <int value="23" label="Reserved (23)"/>
-  <int value="24"
-      label="Header of Literals' block doesn't respect format specification"/>
-  <int value="25" label="Reserved (25)"/>
-  <int value="26" label="Reserved (26)"/>
-  <int value="27" label="Reserved (27)"/>
-  <int value="28" label="Reserved (28)"/>
-  <int value="29" label="Reserved (29)"/>
-  <int value="30" label="Dictionary is corrupted"/>
-  <int value="31" label="Reserved (31)"/>
-  <int value="32" label="Dictionary mismatch"/>
-  <int value="33" label="Reserved (33)"/>
-  <int value="34" label="Cannot create Dictionary from provided samples"/>
-  <int value="35" label="Reserved (35)"/>
-  <int value="36" label="Reserved (36)"/>
-  <int value="37" label="Reserved (37)"/>
-  <int value="38" label="Reserved (38)"/>
-  <int value="39" label="Reserved (39)"/>
-  <int value="40" label="Unsupported parameter"/>
-  <int value="41" label="Unsupported combination of parameters"/>
-  <int value="42" label="Parameter is out of bound"/>
-  <int value="43" label="Reserved (43)"/>
-  <int value="44" label="TableLog requires too much memory : unsupported"/>
-  <int value="45" label="Reserved (45)"/>
-  <int value="46" label="Unsupported max Symbol Value : too large"/>
-  <int value="47" label="Reserved (47)"/>
-  <int value="48" label="Specified maxSymbolValue is too small"/>
-  <int value="49" label="Reserved (49)"/>
-  <int value="50" label="Pledged buffer stability condition is not respected"/>
-  <int value="51" label="Reserved (51)"/>
-  <int value="52" label="Reserved (52)"/>
-  <int value="53" label="Reserved (53)"/>
-  <int value="54" label="Reserved (54)"/>
-  <int value="55" label="Reserved (55)"/>
-  <int value="56" label="Reserved (56)"/>
-  <int value="57" label="Reserved (57)"/>
-  <int value="58" label="Reserved (58)"/>
-  <int value="59" label="Reserved (59)"/>
-  <int value="60" label="Operation not authorized at current processing stage"/>
-  <int value="61" label="Reserved (61)"/>
-  <int value="62" label="Context should be init first"/>
-  <int value="63" label="Reserved (63)"/>
-  <int value="64" label="Allocation error : not enough memory"/>
-  <int value="65" label="Reserved (65)"/>
-  <int value="66" label="WorkSpace buffer is not large enough"/>
-  <int value="67" label="Reserved (67)"/>
-  <int value="68" label="Reserved (68)"/>
-  <int value="69" label="Reserved (69)"/>
-  <int value="70" label="Destination buffer is too small"/>
-  <int value="71" label="Reserved (71)"/>
-  <int value="72" label="Src size is incorrect"/>
-  <int value="73" label="Reserved (73)"/>
-  <int value="74" label="Operation on NULL destination buffer"/>
-  <int value="75" label="Reserved (75)"/>
-  <int value="76" label="Reserved (76)"/>
-  <int value="77" label="Reserved (77)"/>
-  <int value="78" label="Reserved (78)"/>
-  <int value="79" label="Reserved (79)"/>
-  <int value="80"
-      label="Operation made no progress over multiple calls, due to output
-             buffer being full"/>
-  <int value="81" label="Reserved (81)"/>
-  <int value="82"
-      label="Operation made no progress over multiple calls, due to input
-             being empty"/>
-  <int value="83" label="Reserved (83)"/>
-  <int value="84" label="Reserved (84)"/>
-  <int value="85" label="Reserved (85)"/>
-  <int value="86" label="Reserved (86)"/>
-  <int value="87" label="Reserved (87)"/>
-  <int value="88" label="Reserved (88)"/>
-  <int value="89" label="Reserved (89)"/>
-  <int value="90" label="Reserved (90)"/>
-  <int value="91" label="Reserved (91)"/>
-  <int value="92" label="Reserved (92)"/>
-  <int value="93" label="Reserved (93)"/>
-  <int value="94" label="Reserved (94)"/>
-  <int value="95" label="Reserved (95)"/>
-  <int value="96" label="Reserved (96)"/>
-  <int value="97" label="Reserved (97)"/>
-  <int value="98" label="Reserved (98)"/>
-  <int value="99" label="Reserved (99)"/>
-  <int value="100" label="Frame index is too large"/>
-  <int value="101" label="Reserved (101)"/>
-  <int value="102" label="An I/O error occurred when reading/seeking"/>
-  <int value="103" label="Reserved (103)"/>
-  <int value="104" label="Destination buffer is wrong"/>
-  <int value="105" label="Source buffer is wrong"/>
-  <int value="106"
-      label="Block-level external sequence producer returned an error code"/>
-  <int value="107" label="External sequences are not valid"/>
-  <int value="108" label="Reserved (108)"/>
-  <int value="109" label="Reserved (109)"/>
-  <int value="110" label="Reserved (110)"/>
-  <int value="111" label="Reserved (111)"/>
-  <int value="112" label="Reserved (112)"/>
-  <int value="113" label="Reserved (113)"/>
-  <int value="114" label="Reserved (114)"/>
-  <int value="115" label="Reserved (115)"/>
-  <int value="116" label="Reserved (116)"/>
-  <int value="117" label="Reserved (117)"/>
-  <int value="118" label="Reserved (118)"/>
-  <int value="119" label="Reserved (119)"/>
-</enum>
-
 </enums>
 
 </histogram-configuration>
diff --git a/tools/metrics/histograms/histograms_index.txt b/tools/metrics/histograms/histograms_index.txt
index c9616acc..f2d495c 100644
--- a/tools/metrics/histograms/histograms_index.txt
+++ b/tools/metrics/histograms/histograms_index.txt
@@ -63,6 +63,7 @@
 tools/metrics/histograms/metadata/fingerprint/histograms.xml
 tools/metrics/histograms/metadata/game_mode/histograms.xml
 tools/metrics/histograms/metadata/gcm/histograms.xml
+tools/metrics/histograms/metadata/geolocation/enums.xml
 tools/metrics/histograms/metadata/geolocation/histograms.xml
 tools/metrics/histograms/metadata/google/histograms.xml
 tools/metrics/histograms/metadata/gpu/histograms.xml
@@ -92,6 +93,7 @@
 tools/metrics/histograms/metadata/navigation/enums.xml
 tools/metrics/histograms/metadata/navigation/histograms.xml
 tools/metrics/histograms/metadata/nearby/histograms.xml
+tools/metrics/histograms/metadata/net/enums.xml
 tools/metrics/histograms/metadata/net/histograms.xml
 tools/metrics/histograms/metadata/network/histograms.xml
 tools/metrics/histograms/metadata/new_tab_page/histograms.xml
diff --git a/tools/metrics/histograms/metadata/accessibility/histograms.xml b/tools/metrics/histograms/metadata/accessibility/histograms.xml
index aea82c3..e24a1c4 100644
--- a/tools/metrics/histograms/metadata/accessibility/histograms.xml
+++ b/tools/metrics/histograms/metadata/accessibility/histograms.xml
@@ -417,7 +417,7 @@
 </histogram>
 
 <histogram name="Accessibility.Android.UpdateAccessibilityServices.DidPoll"
-    units="BooleanHit" expires_after="2024-02-25">
+    units="BooleanHit" expires_after="2024-05-05">
   <owner>mschillaci@google.com</owner>
   <owner>aldietz@google.com</owner>
   <owner>chrome-a11y-core@google.com</owner>
@@ -428,7 +428,7 @@
 </histogram>
 
 <histogram name="Accessibility.Android.UpdateAccessibilityServices.PollCount"
-    units="count" expires_after="2024-02-25">
+    units="count" expires_after="2024-05-05">
   <owner>mschillaci@google.com</owner>
   <owner>aldietz@google.com</owner>
   <owner>chrome-a11y-core@google.com</owner>
@@ -440,7 +440,7 @@
 </histogram>
 
 <histogram name="Accessibility.Android.UpdateAccessibilityServices.PollTimeout"
-    units="BooleanHit" expires_after="2024-02-25">
+    units="BooleanHit" expires_after="2024-05-05">
   <owner>mschillaci@google.com</owner>
   <owner>aldietz@google.com</owner>
   <owner>chrome-a11y-core@google.com</owner>
@@ -453,7 +453,7 @@
 </histogram>
 
 <histogram name="Accessibility.Android.UpdateAccessibilityServices.Runtime"
-    units="microseconds" expires_after="2024-02-25">
+    units="microseconds" expires_after="2024-05-05">
   <owner>mschillaci@google.com</owner>
   <owner>aldietz@google.com</owner>
   <owner>chrome-a11y-core@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/account_manager/histograms.xml b/tools/metrics/histograms/metadata/account_manager/histograms.xml
index 88aa7137..fcf74ec 100644
--- a/tools/metrics/histograms/metadata/account_manager/histograms.xml
+++ b/tools/metrics/histograms/metadata/account_manager/histograms.xml
@@ -50,7 +50,7 @@
 </histogram>
 
 <histogram name="AccountManager.EduCoexistence.FetchAccessTokenResult"
-    enum="GoogleServiceAuthError" expires_after="2024-03-03">
+    enum="GoogleServiceAuthError" expires_after="2024-05-05">
   <owner>agawronska@chromium.org</owner>
   <owner>cros-families-eng@google.com</owner>
   <summary>
@@ -160,7 +160,7 @@
 </histogram>
 
 <histogram name="AccountManager.NumAccounts" units="count"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>sinhak@chromium.org</owner>
   <owner>anastasiian@chromium.org</owner>
   <summary>
@@ -170,7 +170,7 @@
 </histogram>
 
 <histogram name="AccountManager.ReportAuthError.IsAccountKeyEmpty"
-    enum="BooleanEmpty" expires_after="2024-03-03">
+    enum="BooleanEmpty" expires_after="2024-05-05">
   <owner>sinhak@chromium.org</owner>
   <owner>anastasiian@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml
index 5a9ff3e..f30fae3 100644
--- a/tools/metrics/histograms/metadata/android/histograms.xml
+++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -607,7 +607,7 @@
 </histogram>
 
 <histogram name="Android.BackPress.Interval" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>lazzzis@chromium.org</owner>
   <owner>src/chrome/browser/back_press/android/OWNERS</owner>
   <summary>
@@ -2940,7 +2940,7 @@
 </histogram>
 
 <histogram name="Android.PackageStats.CacheSize" units="MB"
-    expires_after="2024-03-05">
+    expires_after="2024-05-05">
   <owner>nyquist@chromium.org</owner>
   <owner>yfriedman@chromium.org</owner>
   <summary>
@@ -2949,7 +2949,7 @@
 </histogram>
 
 <histogram name="Android.PackageStats.CodeSize" units="MB"
-    expires_after="2024-03-05">
+    expires_after="2024-05-05">
   <owner>nyquist@chromium.org</owner>
   <owner>yfriedman@chromium.org</owner>
   <summary>
@@ -2960,7 +2960,7 @@
 </histogram>
 
 <histogram name="Android.PackageStats.DataSize" units="MB"
-    expires_after="2024-03-05">
+    expires_after="2024-05-05">
   <owner>nyquist@chromium.org</owner>
   <owner>yfriedman@chromium.org</owner>
   <summary>
@@ -4208,7 +4208,7 @@
 </histogram>
 
 <histogram name="Android.TabStrip.DelayTempStripRemovalTimedOut"
-    enum="BooleanTimedOut" expires_after="2024-03-03">
+    enum="BooleanTimedOut" expires_after="2024-05-05">
   <owner>nemco@google.com</owner>
   <owner>skavuluru@google.com</owner>
   <owner>twellington@chromium.org</owner>
@@ -4307,7 +4307,7 @@
 </histogram>
 
 <histogram name="Android.TabStrip.TimeToBufferSwapAfterInitializeTabState"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>nemco@google.com</owner>
   <owner>skavuluru@google.com</owner>
   <owner>twellington@chromium.org</owner>
@@ -4322,7 +4322,7 @@
 </histogram>
 
 <histogram name="Android.TabStrip.TimeToInitializeTabStateAfterBufferSwap"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>nemco@google.com</owner>
   <owner>skavuluru@google.com</owner>
   <owner>twellington@chromium.org</owner>
@@ -4337,7 +4337,7 @@
 </histogram>
 
 <histogram name="Android.TabStrip.TimeToSwitchTab" units="ms"
-    expires_after="2024-02-25">
+    expires_after="2024-05-05">
   <owner>gauravjj@google.com</owner>
   <owner>twellington@chromium.org</owner>
   <owner>clank-large-form-factors@google.com</owner>
@@ -5404,7 +5404,7 @@
 </histogram>
 
 <histogram name="Android.WebView.NonEmbeddedMetrics.NumHistograms"
-    units="histograms" expires_after="2024-03-03">
+    units="histograms" expires_after="2024-05-05">
   <owner>ntfschr@chromium.org</owner>
   <owner>hazems@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
@@ -5836,7 +5836,7 @@
 </histogram>
 
 <histogram name="Android.WebView.Startup.CreationTime.Stage1.FactoryInit"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>torne@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
@@ -5858,7 +5858,7 @@
 </histogram>
 
 <histogram name="Android.WebView.Startup.CreationTime.Stage2.ProviderInit.Warm"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>torne@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/apps/histograms.xml b/tools/metrics/histograms/metadata/apps/histograms.xml
index f97a7ad..4dd1cf3 100644
--- a/tools/metrics/histograms/metadata/apps/histograms.xml
+++ b/tools/metrics/histograms/metadata/apps/histograms.xml
@@ -167,7 +167,7 @@
 </variants>
 
 <histogram name="AppManagement.AppDetailViews" enum="AppManagementUserAction"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
 <!-- Name completed by histogram_suffixes name="AppType" -->
 
   <owner>sharminzaman@google.com</owner>
@@ -183,7 +183,7 @@
 </histogram>
 
 <histogram name="AppManagement.EntryPoints" enum="AppManagementEntryPoint"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>sharminzaman@google.com</owner>
   <owner>tsergeant@chromium.org</owner>
   <owner>chromeos-apps-foundation-team@google.com</owner>
@@ -404,7 +404,7 @@
 
 <histogram
     name="Apps.AppList.CardifiedStateAnimation.AnimationSmoothness{EnterOrExitCardifiedState}"
-    units="%" expires_after="2024-02-20">
+    units="%" expires_after="2024-05-05">
   <owner>anasalazar@chromium.org</owner>
   <owner>tbarzic@chromium.org</owner>
   <summary>
@@ -1889,7 +1889,7 @@
 </histogram>
 
 <histogram name="Apps.AppShimSignatureValidationResult"
-    enum="WebAppShimSignatureValidationResult" expires_after="2024-01-01">
+    enum="WebAppShimSignatureValidationResult" expires_after="2024-05-05">
   <owner>markrowe@chromium.org</owner>
   <owner>chrome-platform-security-core@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/arc/histograms.xml b/tools/metrics/histograms/metadata/arc/histograms.xml
index 8033c442..c626a85 100644
--- a/tools/metrics/histograms/metadata/arc/histograms.xml
+++ b/tools/metrics/histograms/metadata/arc/histograms.xml
@@ -285,7 +285,7 @@
 </histogram>
 
 <histogram name="Arc.AdbSideloadingEnablingScreen"
-    enum="AdbSideloadingPromptEvent" expires_after="2024-03-01">
+    enum="AdbSideloadingPromptEvent" expires_after="2024-05-05">
   <owner>vraheja@chromium.org</owner>
   <owner>tbuckley@chromium.org</owner>
   <summary>
@@ -296,7 +296,7 @@
   </summary>
 </histogram>
 
-<histogram name="Arc.AndroidBootTime" units="ms" expires_after="2024-03-01">
+<histogram name="Arc.AndroidBootTime" units="ms" expires_after="2024-05-05">
   <owner>khmel@google.com</owner>
   <owner>arc-performance@google.com</owner>
   <summary>The time elapsed for booting up the ARC instance.</summary>
@@ -366,7 +366,7 @@
   </summary>
 </histogram>
 
-<histogram name="Arc.Anr.{AnrPeriod}" units="ANRs" expires_after="2024-03-01">
+<histogram name="Arc.Anr.{AnrPeriod}" units="ANRs" expires_after="2024-05-05">
   <owner>khmel@google.com</owner>
   <owner>alanding@google.com</owner>
   <owner>arc-performance@google.com</owner>
@@ -377,7 +377,7 @@
 </histogram>
 
 <histogram name="Arc.Anr.{AnrPeriod}.{ArcBootType}" units="ANRs"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>khmel@google.com</owner>
   <owner>arc-performance@google.com</owner>
   <summary>
@@ -388,7 +388,7 @@
   <token key="ArcBootType" variants="ArcBootTypes"/>
 </histogram>
 
-<histogram name="Arc.Anr.{AnrSource}" enum="ArcAnr" expires_after="2024-03-01">
+<histogram name="Arc.Anr.{AnrSource}" enum="ArcAnr" expires_after="2024-05-05">
   <owner>khmel@google.com</owner>
   <owner>alanding@google.com</owner>
   <owner>arc-performance@google.com</owner>
@@ -1062,7 +1062,7 @@
 </histogram>
 
 <histogram name="Arc.CpuRestrictionDisabled{ArcThrottleObservers}" units="ms"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>khmel@google.com</owner>
   <owner>alanding@google.com</owner>
   <owner>arc-performance@google.com</owner>
@@ -1089,7 +1089,7 @@
 </histogram>
 
 <histogram name="Arc.CpuRestrictionVmResult" enum="ArcCpuRestrictionVmResult"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>khmel@google.com</owner>
   <owner>alanding@google.com</owner>
   <owner>arc-performance@google.com</owner>
@@ -1178,7 +1178,7 @@
 </histogram>
 
 <histogram name="Arc.DelayedActivation.ActivationIsDelayed" enum="Boolean"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hashimoto@chromium.org</owner>
   <owner>yuholong@chromium.org</owner>
   <owner>arcvm-eng@google.com</owner>
@@ -1292,7 +1292,7 @@
 </histogram>
 
 <histogram name="Arc.FirstAppLaunchDelay.TimeDelta" units="ms"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>khmel@google.com</owner>
   <owner>arc-performance@google.com</owner>
   <summary>
@@ -1306,7 +1306,7 @@
 </histogram>
 
 <histogram name="Arc.FirstAppLaunchDelay.TimeDeltaUntilAppLaunch" units="ms"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>khmel@google.com</owner>
   <owner>alanding@google.com</owner>
   <summary>
@@ -1329,7 +1329,7 @@
 </histogram>
 
 <histogram name="Arc.Fixup.Entire.Failures" units="units"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>momohatt@google.com</owner>
   <owner>arc-storage@google.com</owner>
   <summary>
@@ -1340,7 +1340,7 @@
 </histogram>
 
 <histogram name="Arc.Fixup.{Scale}.Directories" units="units"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>momohatt@google.com</owner>
   <owner>arc-storage@google.com</owner>
   <summary>
@@ -1354,7 +1354,7 @@
 </histogram>
 
 <histogram name="Arc.Fixup.{Scale}.Duration" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>momohatt@google.com</owner>
   <owner>arc-storage@google.com</owner>
   <summary>
@@ -2173,7 +2173,7 @@
 
 <histogram
     name="Arc.Runtime.Performance.CommitDeviation2{ArcPerformanceAppCategories}"
-    units="microseconds" expires_after="2024-03-01">
+    units="microseconds" expires_after="2024-05-05">
   <owner>khmel@google.com</owner>
   <owner>alanding@google.com</owner>
   <summary>
@@ -2188,7 +2188,7 @@
 </histogram>
 
 <histogram name="Arc.Runtime.Performance.FPS2{ArcPerformanceAppCategories}"
-    units="fps" expires_after="2024-03-01">
+    units="fps" expires_after="2024-05-05">
   <owner>khmel@google.com</owner>
   <owner>alanding@google.com</owner>
   <summary>
@@ -2202,7 +2202,7 @@
 </histogram>
 
 <histogram name="Arc.Runtime.Performance.Generic.FirstFrameRendered" units="ms"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>khmel@google.com</owner>
   <owner>alanding@google.com</owner>
   <summary>
@@ -2213,7 +2213,7 @@
 </histogram>
 
 <histogram name="Arc.Runtime.Performance.Generic.FrameTime" units="ms"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>khmel@google.com</owner>
   <owner>alanding@google.com</owner>
   <summary>
@@ -2223,7 +2223,7 @@
 </histogram>
 
 <histogram name="Arc.Runtime.Performance.Generic.Jankiness" units="%"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>khmel@google.com</owner>
   <owner>alanding@google.com</owner>
   <summary>
@@ -2234,7 +2234,7 @@
 
 <histogram
     name="Arc.Runtime.Performance.RenderQuality2{ArcPerformanceAppCategories}"
-    units="%" expires_after="2024-03-01">
+    units="%" expires_after="2024-05-05">
   <owner>khmel@google.com</owner>
   <owner>alanding@google.com</owner>
   <summary>
@@ -2395,7 +2395,7 @@
 </histogram>
 
 <histogram name="Arc.UiAvailable.AlreadyProvisioned.TimeDelta{ArcUserTypes}"
-    units="ms" expires_after="2024-03-01">
+    units="ms" expires_after="2024-05-05">
   <owner>khmel@google.com</owner>
   <owner>arc-performance@google.com</owner>
   <summary>
@@ -2408,7 +2408,7 @@
 </histogram>
 
 <histogram name="Arc.UiAvailable.InSessionProvisioning.TimeDelta{ArcUserTypes}"
-    units="ms" expires_after="2024-03-01">
+    units="ms" expires_after="2024-05-05">
   <owner>khmel@google.com</owner>
   <owner>arc-performance@google.com</owner>
   <summary>
@@ -2421,7 +2421,7 @@
 </histogram>
 
 <histogram name="Arc.UiAvailable.OobeProvisioning.TimeDelta{ArcUserTypes}"
-    units="ms" expires_after="2024-03-01">
+    units="ms" expires_after="2024-05-05">
   <owner>khmel@google.com</owner>
   <owner>arc-performance@google.com</owner>
   <summary>
@@ -2457,7 +2457,7 @@
 </histogram>
 
 <histogram name="Arc.VmDataMigration.AutoResumeCount" units="count"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>momohatt@google.com</owner>
   <owner>youkichihosoi@google.com</owner>
   <owner>arc-storage@google.com</owner>
@@ -2474,7 +2474,7 @@
 </histogram>
 
 <histogram name="Arc.VmDataMigration.BatteryConsumption" units="%"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>momohatt@google.com</owner>
   <owner>youkichihosoi@google.com</owner>
   <owner>arc-storage@google.com</owner>
@@ -2488,7 +2488,7 @@
 </histogram>
 
 <histogram name="Arc.VmDataMigration.DesiredDiskImageSizeInGB.{SatisfiedOrNot}"
-    units="GB" expires_after="2024-03-03">
+    units="GB" expires_after="2024-05-05">
   <owner>momohatt@google.com</owner>
   <owner>youkichihosoi@google.com</owner>
   <owner>arc-storage@google.com</owner>
@@ -2504,7 +2504,7 @@
 </histogram>
 
 <histogram name="Arc.VmDataMigration.Duration" units="seconds"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>momohatt@google.com</owner>
   <owner>youkichihosoi@google.com</owner>
   <owner>arc-storage@google.com</owner>
@@ -2515,7 +2515,7 @@
 </histogram>
 
 <histogram name="Arc.VmDataMigration.EndStatus"
-    enum="CrOSFileSystemMigrationEndStatus" expires_after="2024-03-03">
+    enum="CrOSFileSystemMigrationEndStatus" expires_after="2024-05-05">
   <owner>momohatt@google.com</owner>
   <owner>youkichihosoi@google.com</owner>
   <owner>arc-storage@google.com</owner>
@@ -2578,7 +2578,7 @@
 </histogram>
 
 <histogram name="Arc.VmDataMigration.InitialBatteryLevel" units="%"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>momohatt@google.com</owner>
   <owner>youkichihosoi@google.com</owner>
   <owner>arc-storage@google.com</owner>
@@ -2601,7 +2601,7 @@
 </histogram>
 
 <histogram name="Arc.VmDataMigration.MigrationFinishReason{ArcUserTypes}"
-    enum="ArcVmDataMigrationFinishReason" expires_after="2024-03-03">
+    enum="ArcVmDataMigrationFinishReason" expires_after="2024-05-05">
   <owner>momohatt@google.com</owner>
   <owner>youkichihosoi@google.com</owner>
   <owner>arc-storage@google.com</owner>
@@ -2612,7 +2612,7 @@
 </histogram>
 
 <histogram name="Arc.VmDataMigration.MigrationStatusOnArcStarted{ArcUserTypes}"
-    enum="ArcVmDataMigrationStatus" expires_after="2024-03-03">
+    enum="ArcVmDataMigrationStatus" expires_after="2024-05-05">
   <owner>momohatt@google.com</owner>
   <owner>youkichihosoi@google.com</owner>
   <owner>arc-storage@google.com</owner>
@@ -2651,7 +2651,7 @@
 </histogram>
 
 <histogram name="Arc.VmDataMigration.NotificationShownForTheFirstTime"
-    enum="BooleanEnabled" expires_after="2024-03-03">
+    enum="BooleanEnabled" expires_after="2024-05-05">
   <owner>momohatt@google.com</owner>
   <owner>youkichihosoi@google.com</owner>
   <owner>arc-storage@google.com</owner>
@@ -2663,7 +2663,7 @@
 
 <histogram
     name="Arc.VmDataMigration.RemainingDays.{ArcVmDataMigrationFrontEndEvents}"
-    units="days" expires_after="2024-03-03">
+    units="days" expires_after="2024-05-05">
   <owner>momohatt@google.com</owner>
   <owner>youkichihosoi@google.com</owner>
   <owner>arc-storage@google.com</owner>
@@ -2689,7 +2689,7 @@
 
 <histogram
     name="Arc.VmDataMigration.RequiredFreeDiskSpaceInGB.{SatisfiedOrNot}"
-    units="GB" expires_after="2024-03-03">
+    units="GB" expires_after="2024-05-05">
   <owner>momohatt@google.com</owner>
   <owner>youkichihosoi@google.com</owner>
   <owner>arc-storage@google.com</owner>
@@ -2719,7 +2719,7 @@
 </histogram>
 
 <histogram name="Arc.VmDataMigration.ScreenEvent.On{ArcVmDataMigrationType}"
-    enum="ArcVmDataMigrationScreenEvent" expires_after="2024-03-03">
+    enum="ArcVmDataMigrationScreenEvent" expires_after="2024-05-05">
   <owner>momohatt@google.com</owner>
   <owner>youkichihosoi@google.com</owner>
   <owner>arc-storage@google.com</owner>
@@ -2758,7 +2758,7 @@
 </histogram>
 
 <histogram name="Arc.VmDataMigration.SetupResult"
-    enum="ArcVmDataMigrationSetupResult" expires_after="2024-03-03">
+    enum="ArcVmDataMigrationSetupResult" expires_after="2024-05-05">
   <owner>momohatt@google.com</owner>
   <owner>youkichihosoi@google.com</owner>
   <owner>arc-storage@google.com</owner>
@@ -2769,7 +2769,7 @@
 </histogram>
 
 <histogram name="Arc.VmDataMigration.StartStatus"
-    enum="CrOSFileSystemMigrationStartStatus" expires_after="2024-03-03">
+    enum="CrOSFileSystemMigrationStartStatus" expires_after="2024-05-05">
   <owner>momohatt@google.com</owner>
   <owner>youkichihosoi@google.com</owner>
   <owner>arc-storage@google.com</owner>
@@ -2780,7 +2780,7 @@
 </histogram>
 
 <histogram name="Arc.VmDataMigration.TotalFiles" units="files"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>momohatt@google.com</owner>
   <owner>youkichihosoi@google.com</owner>
   <owner>arc-storage@google.com</owner>
@@ -2791,7 +2791,7 @@
 </histogram>
 
 <histogram name="Arc.VmDataMigration.TotalSizeMB" units="MB"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>momohatt@google.com</owner>
   <owner>youkichihosoi@google.com</owner>
   <owner>arc-storage@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml
index 8c84963..5fe53ef7 100644
--- a/tools/metrics/histograms/metadata/ash/histograms.xml
+++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -655,7 +655,7 @@
 </histogram>
 
 <histogram name="Ash.BatterySaver.BatteryPercent{BatteryPercentWhen}" units="%"
-    expires_after="M123">
+    expires_after="2024-05-05">
   <owner>cwd@google.com</owner>
   <owner>ckwyee@google.com</owner>
   <summary>The battery charge percent when {BatteryPercentWhen}</summary>
@@ -670,7 +670,7 @@
 </histogram>
 
 <histogram name="Ash.BatterySaver.Duration{DurationWhen}" units="ms"
-    expires_after="M123">
+    expires_after="2024-05-05">
   <owner>cwd@google.com</owner>
   <owner>ckwyee@google.com</owner>
   <summary>
@@ -691,7 +691,7 @@
 </histogram>
 
 <histogram name="Ash.BatterySaver.TimeToEmpty{TimeToEmptyWhen}" units="ms"
-    expires_after="M123">
+    expires_after="2024-05-05">
   <owner>cwd@google.com</owner>
   <owner>ckwyee@google.com</owner>
   <summary>
@@ -2201,7 +2201,7 @@
 </histogram>
 
 <histogram name="Ash.Desks.AnimationSmoothness.DeskActivation" units="%"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>afakhry@chromium.org</owner>
   <owner>tclaiborne@chromium.org</owner>
   <summary>
@@ -3288,7 +3288,7 @@
 </histogram>
 
 <histogram name="Ash.EventLatency.Core.TotalLatency" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>xiyuan@chromium.org</owner>
   <owner>yichenz@chromium.org</owner>
   <owner>cros-sw-perf@google.com</owner>
@@ -3305,7 +3305,7 @@
 </histogram>
 
 <histogram name="Ash.EventLatency.TotalLatency" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>xiyuan@chromium.org</owner>
   <owner>yichenz@chromium.org</owner>
   <owner>cros-sw-perf@google.com</owner>
@@ -3565,7 +3565,7 @@
 </histogram>
 
 <histogram name="Ash.Glanceables.Api.Classroom.{Role}CoursesCount"
-    units="courses" expires_after="2024-03-01">
+    units="courses" expires_after="2024-05-05">
   <owner>amitrokhin@google.com</owner>
   <owner>chromeos-launcher@google.com</owner>
   <summary>
@@ -3596,7 +3596,7 @@
 </histogram>
 
 <histogram name="Ash.Glanceables.Api.Tasks.ProcessedTasksCount" units="tasks"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>amitrokhin@google.com</owner>
   <owner>chromeos-launcher@google.com</owner>
   <summary>
@@ -3642,7 +3642,7 @@
 </histogram>
 
 <histogram name="Ash.Glanceables.Api.{Method}.Latency" units="ms"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>amitrokhin@google.com</owner>
   <owner>chromeos-launcher@google.com</owner>
   <summary>
@@ -3661,7 +3661,7 @@
 </histogram>
 
 <histogram name="Ash.Glanceables.Api.{Method}.PagesCount" units="pages"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>amitrokhin@google.com</owner>
   <owner>chromeos-launcher@google.com</owner>
   <summary>
@@ -3678,7 +3678,7 @@
 </histogram>
 
 <histogram name="Ash.Glanceables.Api.{Method}.Status" enum="ApiErrorCode"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>amitrokhin@google.com</owner>
   <owner>chromeos-launcher@google.com</owner>
   <summary>
@@ -4169,7 +4169,7 @@
 </histogram>
 
 <histogram name="Ash.Login.PinAutosubmit.Backfill"
-    enum="PinAutosubmitBackfillEvent" expires_after="2024-02-20">
+    enum="PinAutosubmitBackfillEvent" expires_after="2024-05-05">
   <owner>emaamari@google.com</owner>
   <owner>rrsilva@google.com</owner>
   <owner>cros-lurs@google.com</owner>
@@ -5025,7 +5025,7 @@
 </histogram>
 
 <histogram name="Ash.OSAuth.Login.ConfiguredAuthFactors.{AuthFactor}"
-    enum="Boolean" expires_after="2024-03-01">
+    enum="Boolean" expires_after="2024-05-05">
   <owner>anastasiian@chromium.org</owner>
   <owner>cros-lurs@google.com</owner>
   <summary>
@@ -5348,7 +5348,7 @@
 </histogram>
 
 <histogram name="Ash.Personalization.AmbientMode.AnimationTheme2"
-    enum="AmbientModeAnimationTheme" expires_after="2024-03-03">
+    enum="AmbientModeAnimationTheme" expires_after="2024-05-05">
   <owner>jasontt@chromium.org</owner>
   <owner>assistive-eng@google.com</owner>
   <summary>
@@ -5747,7 +5747,7 @@
 </histogram>
 
 <histogram name="Ash.PrivacyIndicators.Source" enum="PrivacyIndicatorsSource"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>leandre@chromium.org</owner>
   <owner>cros-status-area-eng@google.com</owner>
   <summary>
@@ -6609,7 +6609,7 @@
 </histogram>
 
 <histogram name="Ash.Snap.CloseTwoWindowsDuration" units="seconds"
-    expires_after="2024-01-14">
+    expires_after="2024-05-05">
   <owner>sophiewen@chromium.org</owner>
   <owner>michelefan@chromium.org</owner>
   <summary>
@@ -6622,7 +6622,7 @@
 </histogram>
 
 <histogram name="Ash.Snap.MinimizeTwoWindowsDuration" units="seconds"
-    expires_after="2024-01-14">
+    expires_after="2024-05-05">
   <owner>sophiewen@chromium.org</owner>
   <owner>michelefan@chromium.org</owner>
   <summary>
@@ -6636,7 +6636,7 @@
 </histogram>
 
 <histogram name="Ash.Snap.SnapTwoWindowsDuration" units="seconds"
-    expires_after="2024-01-14">
+    expires_after="2024-05-05">
   <owner>sophiewen@chromium.org</owner>
   <owner>michelefan@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/ash_user_education/histograms.xml b/tools/metrics/histograms/metadata/ash_user_education/histograms.xml
index b543e80..32a512f 100644
--- a/tools/metrics/histograms/metadata/ash_user_education/histograms.xml
+++ b/tools/metrics/histograms/metadata/ash_user_education/histograms.xml
@@ -29,7 +29,7 @@
 </variants>
 
 <histogram name="Ash.WelcomeTour.Aborted.Reason"
-    enum="WelcomeTourAbortedReason" expires_after="2024-03-03">
+    enum="WelcomeTourAbortedReason" expires_after="2024-05-05">
   <owner>angusmclean@google.com</owner>
   <owner>dmblack@google.com</owner>
   <summary>
@@ -38,7 +38,7 @@
 </histogram>
 
 <histogram name="Ash.WelcomeTour.Prevented.Reason"
-    enum="WelcomeTourPreventedReason" expires_after="2024-03-03">
+    enum="WelcomeTourPreventedReason" expires_after="2024-05-05">
   <owner>angusmclean@google.com</owner>
   <owner>dmblack@google.com</owner>
   <summary>
@@ -75,7 +75,7 @@
 </histogram>
 
 <histogram name="Ash.WelcomeTour.Step.Shown" enum="WelcomeTourStep"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>angusmclean@google.com</owner>
   <owner>dmblack@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/assistant/histograms.xml b/tools/metrics/histograms/metadata/assistant/histograms.xml
index 49a99219..b85ca025 100644
--- a/tools/metrics/histograms/metadata/assistant/histograms.xml
+++ b/tools/metrics/histograms/metadata/assistant/histograms.xml
@@ -165,7 +165,7 @@
 </histogram>
 
 <histogram name="Assistant.QueryCountPerEntryPoint" enum="AssistantEntryPoint"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>xiaohuic@chromium.org</owner>
   <owner>croissant-eng@chromium.org</owner>
   <summary>Number of queries fired for each entry point.</summary>
@@ -219,7 +219,7 @@
 </histogram>
 
 <histogram name="Assistant.ServiceState" enum="AssistantServiceState"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>wutao@chromium.org</owner>
   <owner>assistive-eng@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/auto/histograms.xml b/tools/metrics/histograms/metadata/auto/histograms.xml
index f6b30fa..e8224c4 100644
--- a/tools/metrics/histograms/metadata/auto/histograms.xml
+++ b/tools/metrics/histograms/metadata/auto/histograms.xml
@@ -290,7 +290,7 @@
 </histogram>
 
 <histogram name="AutoScreenBrightness.GlobalCurveResetOnInitialization"
-    enum="Boolean" expires_after="2024-03-03">
+    enum="Boolean" expires_after="2024-05-05">
   <owner>thanhdng@chromium.org</owner>
   <owner>tby@chromium.org</owner>
   <summary>Whether the global curve is reset at initialization.</summary>
@@ -486,7 +486,7 @@
 </histogram>
 
 <histogram name="AutoScreenBrightness.UserAdjustmentEffect"
-    enum="AutoScreenBrightnessUserAdjustmentEffect" expires_after="2024-03-03">
+    enum="AutoScreenBrightnessUserAdjustmentEffect" expires_after="2024-05-05">
   <owner>thanhdng@chromium.org</owner>
   <owner>tby@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/autofill/histograms.xml b/tools/metrics/histograms/metadata/autofill/histograms.xml
index 8b6d580..ca1789a 100644
--- a/tools/metrics/histograms/metadata/autofill/histograms.xml
+++ b/tools/metrics/histograms/metadata/autofill/histograms.xml
@@ -644,7 +644,7 @@
 </histogram>
 
 <histogram name="Autofill.Autocomplete.PredictionCollisionState"
-    enum="PredictionStateAutocompleteStatePair" expires_after="2024-03-03">
+    enum="PredictionStateAutocompleteStatePair" expires_after="2024-05-05">
   <owner>koerber@google.com</owner>
   <owner>fleimgruber@google.com</owner>
   <owner>chrome-autofill-team@google.com</owner>
@@ -2891,7 +2891,7 @@
 </histogram>
 
 <histogram name="Autofill.LogEvent.{LogEventTypes}" units="units"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>battre@chromium.org</owner>
   <owner>chrome-autofill-alerts@google.com</owner>
   <summary>
@@ -3803,7 +3803,7 @@
 </histogram>
 
 <histogram name="Autofill.ProfileImport.MigrateProfileEditedType"
-    enum="AutofillSettingsVisibleTypes" expires_after="2024-02-04">
+    enum="AutofillSettingsVisibleTypes" expires_after="2024-05-05">
   <owner>koerber@google.com</owner>
   <owner>fleimgruber@google.com</owner>
   <owner>src/components/autofill/OWNERS</owner>
@@ -3814,7 +3814,7 @@
 </histogram>
 
 <histogram name="Autofill.ProfileImport.MigrateProfileNumberOfEditedFields"
-    units="fields" expires_after="2024-02-04">
+    units="fields" expires_after="2024-05-05">
   <owner>koerber@google.com</owner>
   <owner>fleimgruber@google.com</owner>
   <owner>src/components/autofill/OWNERS</owner>
@@ -5740,7 +5740,7 @@
 </histogram>
 
 <histogram name="Autofill.WebOTP.PhonePlusWebOTPPlusOTC"
-    enum="PhoneCollectionState" expires_after="2024-02-12">
+    enum="PhoneCollectionState" expires_after="2024-05-05">
   <owner>yigu@chromium.org</owner>
   <owner>web-identity-eng@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml
index aebc168..a15e96f 100644
--- a/tools/metrics/histograms/metadata/blink/histograms.xml
+++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -207,7 +207,7 @@
 </histogram>
 
 <histogram name="Blink.Animation.CompositedAnimationFailureReason"
-    enum="CompositorAnimationsFailureReason" expires_after="2024-03-01">
+    enum="CompositorAnimationsFailureReason" expires_after="2024-05-05">
   <owner>smcgruer@chromium.org</owner>
   <owner>animations-dev@chromium.org</owner>
   <summary>
@@ -1591,7 +1591,7 @@
 </histogram>
 
 <histogram name="Blink.FedCm.Status.IdpSigninMatch"
-    enum="FedCmIdpSigninMatchStatus" expires_after="2024-03-03">
+    enum="FedCmIdpSigninMatchStatus" expires_after="2024-05-05">
   <owner>cbiesinger@chromium.org</owner>
   <owner>web-identity-eng@google.com</owner>
   <summary>
@@ -2702,7 +2702,7 @@
 </histogram>
 
 <histogram name="Blink.Layout.RebuildFragmentTreeSpine" units="microseconds"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>tkent@chromium.org</owner>
   <owner>layout-dev@chromium.org</owner>
   <summary>
@@ -2712,7 +2712,7 @@
 </histogram>
 
 <histogram name="Blink.Layout.UpdateLayerPositionsAfterLayout"
-    units="microseconds" expires_after="2024-03-03">
+    units="microseconds" expires_after="2024-05-05">
   <owner>pdr@chromium.org</owner>
   <owner>ikilpatrick@chromium.org</owner>
   <owner>layout-dev@chromium.org</owner>
@@ -3086,7 +3086,7 @@
 </histogram>
 
 <histogram name="Blink.MemoryCache.CrossDocumentCachedResource2"
-    enum="ResourceType" expires_after="2024-03-03">
+    enum="ResourceType" expires_after="2024-05-05">
   <owner>gjc@chromium.org</owner>
   <owner>blink-network-dev@chromium.org</owner>
   <summary>
@@ -4111,7 +4111,7 @@
 </histogram>
 
 <histogram name="Blink.UseCounter.FencedFrames.MainFrame.Features"
-    enum="FeatureObserver" expires_after="2024-03-03">
+    enum="FeatureObserver" expires_after="2024-05-05">
   <owner>toyoshim@chromium.org</owner>
   <owner>mparc-dev@chromium.org</owner>
   <summary>
@@ -4178,7 +4178,7 @@
 </histogram>
 
 <histogram name="Blink.UseCounter.File.Features" enum="FeatureObserver"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>yhirano@chromium.org</owner>
   <owner>mkwst@chromium.org</owner>
   <summary>
@@ -4242,7 +4242,7 @@
 </histogram>
 
 <histogram name="Blink.UseCounter.PermissionsPolicy.Violation.Enforce"
-    enum="FeaturePolicyFeature" expires_after="2024-01-22">
+    enum="FeaturePolicyFeature" expires_after="2024-05-05">
   <owner>iclelland@chromium.org</owner>
   <owner>feature-control@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/bluetooth/histograms.xml b/tools/metrics/histograms/metadata/bluetooth/histograms.xml
index e30e61b..1a82428b 100644
--- a/tools/metrics/histograms/metadata/bluetooth/histograms.xml
+++ b/tools/metrics/histograms/metadata/bluetooth/histograms.xml
@@ -53,7 +53,7 @@
 </variants>
 
 <histogram name="Bluetooth.BlueZ.DBus.{MethodName}.Latency" units="ms"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>Tracks the latency of the BlueZ {MethodName} DBus method.</summary>
@@ -61,7 +61,7 @@
 </histogram>
 
 <histogram name="Bluetooth.BlueZ.DBus.{MethodName}.Result" enum="DBusResult"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>Tracks the result for BlueZ {MethodName} DBus method calls.</summary>
@@ -69,7 +69,7 @@
 </histogram>
 
 <histogram name="Bluetooth.ChromeOS.DeviceConnected.{ConnectionType}"
-    enum="BluetoothDeviceType" expires_after="2024-03-01">
+    enum="BluetoothDeviceType" expires_after="2024-05-05">
   <owner>khorimoto@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>
@@ -1590,7 +1590,7 @@
 
 <histogram
     name="Bluetooth.ChromeOS.Pairing.Duration.Success{BluetoothTransportTypes}"
-    units="ms" expires_after="2024-03-01">
+    units="ms" expires_after="2024-05-05">
   <owner>khorimoto@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>
@@ -1606,7 +1606,7 @@
 
 <histogram
     name="Bluetooth.ChromeOS.Pairing.Result.FailureReason{BluetoothTransportTypes}"
-    enum="BluetoothConnectionFailureReason" expires_after="2024-03-01">
+    enum="BluetoothConnectionFailureReason" expires_after="2024-05-05">
   <owner>khorimoto@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>
@@ -1643,7 +1643,7 @@
 </histogram>
 
 <histogram name="Bluetooth.ChromeOS.Pairing.Result{BluetoothTransportTypes}"
-    enum="BooleanSuccess" expires_after="2024-03-01">
+    enum="BooleanSuccess" expires_after="2024-05-05">
   <owner>khorimoto@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>
@@ -1683,7 +1683,7 @@
 </histogram>
 
 <histogram name="Bluetooth.ChromeOS.PoweredState.{Operation}.Result"
-    enum="BooleanSuccess" expires_after="2024-03-01">
+    enum="BooleanSuccess" expires_after="2024-05-05">
   <owner>khorimoto@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>Record emitted when an {Operation}.</summary>
@@ -1695,7 +1695,7 @@
 </histogram>
 
 <histogram name="Bluetooth.ChromeOS.SetNickname.Result"
-    enum="SetNicknameResult" expires_after="2024-03-01">
+    enum="SetNicknameResult" expires_after="2024-05-05">
   <owner>khorimoto@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>Emitted each time a nickname change attempt completes.</summary>
@@ -1738,7 +1738,7 @@
 
 <histogram
     name="Bluetooth.ChromeOS.UserInitiatedReconnectionAttempt.Duration.Success{BluetoothTransportTypes}"
-    units="ms" expires_after="2024-03-01">
+    units="ms" expires_after="2024-05-05">
   <owner>khorimoto@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>
@@ -1752,7 +1752,7 @@
 
 <histogram
     name="Bluetooth.ChromeOS.UserInitiatedReconnectionAttempt.Result.FailureReason{UserInitiatedReconnectionUISurfaces}"
-    enum="BluetoothConnectionFailureReason" expires_after="2024-03-01">
+    enum="BluetoothConnectionFailureReason" expires_after="2024-05-05">
   <owner>khorimoto@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>
@@ -1771,7 +1771,7 @@
 
 <histogram
     name="Bluetooth.ChromeOS.UserInitiatedReconnectionAttempt.Result{UserInitiatedReconnectionUISurfaces}"
-    enum="BooleanSuccess" expires_after="2024-03-01">
+    enum="BooleanSuccess" expires_after="2024-05-05">
   <owner>khorimoto@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>
@@ -1845,7 +1845,7 @@
 </histogram>
 
 <histogram name="Bluetooth.Mojo.PendingConnectAtShutdown.DurationWaiting"
-    units="ms" expires_after="2024-03-01">
+    units="ms" expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>cros-system-services-networking@google.com</owner>
   <summary>
@@ -1857,7 +1857,7 @@
 
 <histogram
     name="Bluetooth.Mojo.PendingConnectAtShutdown.NumberOfServiceDiscoveriesInProgress"
-    units="count" expires_after="2024-03-01">
+    units="count" expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>cros-system-services-networking@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/bookmarks/histograms.xml b/tools/metrics/histograms/metadata/bookmarks/histograms.xml
index 81897e0..02743f4 100644
--- a/tools/metrics/histograms/metadata/bookmarks/histograms.xml
+++ b/tools/metrics/histograms/metadata/bookmarks/histograms.xml
@@ -171,6 +171,15 @@
   </summary>
 </histogram>
 
+<histogram name="Bookmarks.BookmarkBar.Shown" enum="BooleanShown"
+    expires_after="2024-04-28">
+  <owner>amelies@chromium.org</owner>
+  <owner>chrome-signin-team@google.com</owner>
+  <summary>
+    Records whether the bookmark bar is shown at startup or not.
+  </summary>
+</histogram>
+
 <histogram name="Bookmarks.BookmarksBar.DragDropType"
     enum="BookmarkBarDragDropType" expires_after="2024-04-28">
   <owner>dfried@chromium.org</owner>
@@ -447,7 +456,7 @@
 </histogram>
 
 <histogram name="Bookmarks.ParentFolderType" enum="BookmarkFolderType"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>emshack@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
   <component>UI&gt;Browser&gt;Bookmarks</component>
@@ -469,7 +478,7 @@
 </histogram>
 
 <histogram name="Bookmarks.ReadingList.NumberOfReadItems" units="items"
-    expires_after="2024-01-20">
+    expires_after="2024-05-05">
   <owner>wylieb@chromium.org</owner>
   <component>UI&gt;Browser&gt;Bookmarks</component>
   <component>UI&gt;Browser&gt;Mobile&gt;ReadingList</component>
@@ -480,7 +489,7 @@
 </histogram>
 
 <histogram name="Bookmarks.ReadingList.NumberOfUnreadItems" units="items"
-    expires_after="2024-01-20">
+    expires_after="2024-05-05">
   <owner>wylieb@chromium.org</owner>
   <component>UI&gt;Browser&gt;Bookmarks</component>
   <component>UI&gt;Browser&gt;Mobile&gt;ReadingList</component>
diff --git a/tools/metrics/histograms/metadata/browser/histograms.xml b/tools/metrics/histograms/metadata/browser/histograms.xml
index b57d47ec..9d80b25 100644
--- a/tools/metrics/histograms/metadata/browser/histograms.xml
+++ b/tools/metrics/histograms/metadata/browser/histograms.xml
@@ -50,6 +50,16 @@
       summary="Tab has a saved frame in the cache."/>
 </variants>
 
+<histogram name="Browser.Actions.PinnedActionsCount" units="actions"
+    expires_after="2024-03-17">
+  <owner>corising@chromium.org</owner>
+  <owner>chrome-desktop-ui-sea@google.com</owner>
+  <summary>
+    Records the number of actions that are currently pinned to the toolbar. This
+    is emitted every time the user pins or unpins an action to the toolbar.
+  </summary>
+</histogram>
+
 <histogram name="Browser.BitmapFetcher.Decode" units="ms"
     expires_after="2022-09-18">
   <obsolete>
@@ -305,7 +315,7 @@
 </histogram>
 
 <histogram name="Browser.ERP.{ManagementStatus}UploadEncryptedReport"
-    enum="EnterpriseDMServerRequestSuccess" expires_after="2024-03-01">
+    enum="EnterpriseDMServerRequestSuccess" expires_after="2024-05-05">
   <owner>jrhilke@google.com</owner>
   <owner>src/components/reporting/OWNERS</owner>
   <summary>
@@ -741,7 +751,7 @@
 </histogram>
 
 <histogram name="Browser.Tabs.SelectionToVisibilityRequestTime"
-    units="microseconds" expires_after="2024-03-03">
+    units="microseconds" expires_after="2024-05-05">
   <owner>jonross@chromium.org</owner>
   <owner>sky@chromium.org</owner>
   <summary>
@@ -1055,7 +1065,7 @@
 </histogram>
 
 <histogram name="BrowserServices.VerificationTime.Online" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>peconn@chromium.org</owner>
   <owner>peter@chromium.org</owner>
   <summary>
@@ -1214,7 +1224,7 @@
 </histogram>
 
 <histogram name="BrowserSwitcher.UrlListWildcard" enum="BooleanPresent"
-    expires_after="2024-03-05">
+    expires_after="2024-05-05">
   <owner>nicolaso@chromium.org</owner>
   <owner>pastarmovj@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/browsing_topics/histograms.xml b/tools/metrics/histograms/metadata/browsing_topics/histograms.xml
index a3a10fea4a..3550318 100644
--- a/tools/metrics/histograms/metadata/browsing_topics/histograms.xml
+++ b/tools/metrics/histograms/metadata/browsing_topics/histograms.xml
@@ -166,7 +166,7 @@
 </histogram>
 
 <histogram name="BrowsingTopics.Result.FakeTopicCount" units="topics"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>yaoxia@chromium.org</owner>
   <owner>jkarlin@chromium.org</owner>
   <summary>
@@ -176,7 +176,7 @@
 </histogram>
 
 <histogram name="BrowsingTopics.Result.FilteredTopicCount" units="topics"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>yaoxia@chromium.org</owner>
   <owner>jkarlin@chromium.org</owner>
   <summary>
@@ -187,7 +187,7 @@
 </histogram>
 
 <histogram name="BrowsingTopics.Result.RealTopicCount" units="topics"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>yaoxia@chromium.org</owner>
   <owner>jkarlin@chromium.org</owner>
   <summary>
@@ -197,7 +197,7 @@
 </histogram>
 
 <histogram name="BrowsingTopics.Result.Status"
-    enum="BrowsingTopicsApiAccessResult" expires_after="2024-03-01">
+    enum="BrowsingTopicsApiAccessResult" expires_after="2024-05-05">
   <owner>yaoxia@chromium.org</owner>
   <owner>jkarlin@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/chromeos/histograms.xml b/tools/metrics/histograms/metadata/chromeos/histograms.xml
index 9e3fed52..c027362 100644
--- a/tools/metrics/histograms/metadata/chromeos/histograms.xml
+++ b/tools/metrics/histograms/metadata/chromeos/histograms.xml
@@ -1271,7 +1271,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Gaia.Message.{GaiaAuthFlow}.{MessageName}"
-    enum="BooleanReceived" expires_after="2024-03-03">
+    enum="BooleanReceived" expires_after="2024-05-05">
   <owner>rsorokin@google.com</owner>
   <owner>cros-3pidp@google.com</owner>
   <summary>
@@ -1365,7 +1365,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Healthd.DiagnosticResult.{Routine}"
-    enum="CrosHealthdDiagnosticResult" expires_after="2024-03-03">
+    enum="CrosHealthdDiagnosticResult" expires_after="2024-05-05">
   <owner>weiluanwang@google.com</owner>
   <owner>dennyh@google.com</owner>
   <owner>cros-tdm-tpe-eng@google.com</owner>
@@ -1436,7 +1436,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Healthd.TelemetryResult.{Category}"
-    enum="CrosHealthdTelemetryResult" expires_after="2024-03-03">
+    enum="CrosHealthdTelemetryResult" expires_after="2024-05-05">
   <owner>weiluanwang@google.com</owner>
   <owner>dennyh@google.com</owner>
   <owner>cros-tdm-tpe-eng@google.com</owner>
@@ -2295,7 +2295,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Secagentd.Bootmode.Cros" enum="SecagentdBootmodeCros"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>rborzello@google.com</owner>
   <owner>cros-enterprise-security@google.com</owner>
   <summary>
@@ -2307,7 +2307,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Secagentd.Bootmode.Uefi" enum="SecagentdBootmodeUefi"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>rborzello@google.com</owner>
   <owner>cros-enterprise-security@google.com</owner>
   <summary>
@@ -2319,7 +2319,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Secagentd.Bpf.{Bpf}.AttachResult"
-    enum="SecagentdBpfAttachResult" expires_after="2024-03-01">
+    enum="SecagentdBpfAttachResult" expires_after="2024-05-05">
   <owner>rborzello@google.com</owner>
   <owner>cros-enterprise-security@google.com</owner>
   <summary>
@@ -2334,7 +2334,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Secagentd.Cache" enum="SecagentdCache"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>rborzello@google.com</owner>
   <owner>cros-enterprise-security@google.com</owner>
   <summary>
@@ -2346,7 +2346,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Secagentd.CacheFullness" units="%"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>rborzello@google.com</owner>
   <owner>cros-enterprise-security@google.com</owner>
   <summary>
@@ -2356,7 +2356,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Secagentd.Policy" enum="SecagentdPolicy"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>rborzello@google.com</owner>
   <owner>cros-enterprise-security@google.com</owner>
   <summary>
@@ -2372,7 +2372,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Secagentd.Process.{EventType}Event"
-    enum="SecagentdProcessEvent" expires_after="2024-03-01">
+    enum="SecagentdProcessEvent" expires_after="2024-05-05">
   <owner>rborzello@google.com</owner>
   <owner>cros-enterprise-security@google.com</owner>
   <summary>
@@ -2387,7 +2387,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Secagentd.Redaction" units="position"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>rborzello@google.com</owner>
   <owner>cros-enterprise-security@google.com</owner>
   <summary>
@@ -2399,7 +2399,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Secagentd.SendMessageResult"
-    enum="SecagentdSendMessageResult" expires_after="2024-03-01">
+    enum="SecagentdSendMessageResult" expires_after="2024-05-05">
   <owner>rborzello@google.com</owner>
   <owner>cros-enterprise-security@google.com</owner>
   <summary>
@@ -2410,7 +2410,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Secagentd.Tpm" enum="SecagentdTpm"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>rborzello@google.com</owner>
   <owner>cros-enterprise-security@google.com</owner>
   <summary>
@@ -3206,7 +3206,7 @@
 </histogram>
 
 <histogram base="true" name="ChromeOS.SystemTray.AnimationSmoothness" units="%"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
 <!-- Name completed by histogram suffixes
      name="SystemTrayTransitionType" -->
 
diff --git a/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml b/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml
index bdd9980..cd5846f 100644
--- a/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml
+++ b/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml
@@ -77,7 +77,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Settings.Apps.DoNotDisturbOnOff"
-    enum="BooleanToggled" expires_after="2024-03-03">
+    enum="BooleanToggled" expires_after="2024-05-05">
   <owner>hsuregan@chromium.org</owner>
   <owner>jimmyxgong@chromium.org</owner>
   <summary>
@@ -119,7 +119,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Settings.Device.KeyboardAutoRepeatEnabled"
-    enum="BooleanEnabled" expires_after="2024-03-03">
+    enum="BooleanEnabled" expires_after="2024-05-05">
   <owner>ckincaid@chromium.org</owner>
   <owner>dmblack@google.com</owner>
   <owner>cros-settings@google.com</owner>
@@ -489,7 +489,7 @@
 </histogram>
 
 <histogram name="ChromeOS.Settings.SearchRequests"
-    enum="OsSettingSearchRequestTypes" expires_after="2024-02-25">
+    enum="OsSettingSearchRequestTypes" expires_after="2024-05-05">
   <owner>wesokuhara@google.com</owner>
   <owner>xiaohuic@chromium.org</owner>
   <owner>cros-settings@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/companion/histograms.xml b/tools/metrics/histograms/metadata/companion/histograms.xml
index 4a55520..e94e6c4c 100644
--- a/tools/metrics/histograms/metadata/companion/histograms.xml
+++ b/tools/metrics/histograms/metadata/companion/histograms.xml
@@ -68,7 +68,7 @@
 </histogram>
 
 <histogram name="Companion.HasNavigatedToExpsSuccessPagePref.Status"
-    enum="Boolean" expires_after="2024-03-03">
+    enum="Boolean" expires_after="2024-05-05">
   <owner>tbansal@chromium.org</owner>
   <owner>src/chrome/browser/companion/OWNERS</owner>
   <summary>
@@ -244,7 +244,7 @@
 </histogram>
 
 <histogram name="Companion.VisualQuery.EligibilityStatus.NumSensitive"
-    units="images" expires_after="2024-03-03">
+    units="images" expires_after="2024-05-05">
   <owner>srna@google.com</owner>
   <owner>pstjuste@google.com</owner>
   <owner>src/chrome/browser/companion/OWNERS</owner>
diff --git a/tools/metrics/histograms/metadata/compositing/histograms.xml b/tools/metrics/histograms/metadata/compositing/histograms.xml
index fea00bf7..ac7c81a 100644
--- a/tools/metrics/histograms/metadata/compositing/histograms.xml
+++ b/tools/metrics/histograms/metadata/compositing/histograms.xml
@@ -834,7 +834,7 @@
 </histogram>
 
 <histogram name="Compositing.SurfaceAggregator.PrewalkUs" units="microseconds"
-    expires_after="2024-02-01">
+    expires_after="2024-05-05">
   <owner>kylechar@chromium.org</owner>
   <owner>jonross@chromium.org</owner>
   <summary>
@@ -1061,7 +1061,7 @@
 </histogram>
 
 <histogram name="Graphics.Exo.Smoothness.DidNotProduceToFrameArrival"
-    units="microseconds" expires_after="2024-03-03">
+    units="microseconds" expires_after="2024-05-05">
   <owner>jonross@chromium.org</owner>
   <owner>yzshen@chromium.org</owner>
   <owner>graphics-dev@chromium.org</owner>
@@ -1080,7 +1080,7 @@
 </histogram>
 
 <histogram name="Graphics.Exo.Smoothness.PercentDidNotProduceFrame" units="%"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jonross@chromium.org</owner>
   <owner>yzshen@chromium.org</owner>
   <owner>graphics-dev@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/content/histograms.xml b/tools/metrics/histograms/metadata/content/histograms.xml
index 24650fa..c9f29de4 100644
--- a/tools/metrics/histograms/metadata/content/histograms.xml
+++ b/tools/metrics/histograms/metadata/content/histograms.xml
@@ -976,7 +976,7 @@
 </histogram>
 
 <histogram name="ContentSuggestions.Feed.DisplayStatusOnOpen"
-    enum="ContentSuggestionsDisplayStatus" expires_after="2024-01-14">
+    enum="ContentSuggestionsDisplayStatus" expires_after="2024-05-05">
   <owner>carlosk@chromium.org</owner>
   <owner>harringtond@chromium.org</owner>
   <owner>feed@chromium.org</owner>
@@ -1266,7 +1266,7 @@
 </histogram>
 
 <histogram name="ContentSuggestions.Feed.SignInFromFeedAction.SignInSuccessful"
-    enum="Boolean" expires_after="2024-03-03">
+    enum="Boolean" expires_after="2024-05-05">
   <owner>birnie@google.com</owner>
   <owner>feed@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/cookie/histograms.xml b/tools/metrics/histograms/metadata/cookie/histograms.xml
index dbfa262c..3e3374f 100644
--- a/tools/metrics/histograms/metadata/cookie/histograms.xml
+++ b/tools/metrics/histograms/metadata/cookie/histograms.xml
@@ -23,7 +23,7 @@
 <histograms>
 
 <histogram name="Cookie.AvgCookieJarSizePerKey" units="kibibytes"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>dylancutler@google.com</owner>
   <owner>src/net/cookies/OWNERS</owner>
   <summary>
@@ -308,7 +308,7 @@
 </histogram>
 
 <histogram name="Cookie.DoubleUnderscorePrefixedName" enum="Boolean"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>bingler@chromium.org</owner>
   <owner>miketaylr@chromium.org</owner>
   <summary>
@@ -383,7 +383,7 @@
 </histogram>
 
 <histogram name="Cookie.FirstPartyPartitioned.HasCrossSiteAncestor"
-    enum="BooleanPresent" expires_after="2024-03-03">
+    enum="BooleanPresent" expires_after="2024-05-05">
   <owner>selya@google.com</owner>
   <owner>src/net/cookies/OWNERS</owner>
   <summary>
@@ -928,7 +928,7 @@
 </histogram>
 
 <histogram name="Cookie.RequestSameSiteContext" enum="SameSiteCookieContext"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>bingler@chromium.org</owner>
   <owner>morlovich@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/cross_device/histograms.xml b/tools/metrics/histograms/metadata/cross_device/histograms.xml
index a207083f..c337c56 100644
--- a/tools/metrics/histograms/metadata/cross_device/histograms.xml
+++ b/tools/metrics/histograms/metadata/cross_device/histograms.xml
@@ -261,7 +261,7 @@
 
 <histogram
     name="CryptAuth.DeviceSyncV2.DeviceActivityGetter.ApiCallResult.GetDevicesActivityStatus"
-    enum="CryptAuthApiCallResult" expires_after="2024-03-03">
+    enum="CryptAuthApiCallResult" expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -807,7 +807,7 @@
 </histogram>
 
 <histogram name="CryptAuth.DeviceSyncV2.Result.ResultCode"
-    enum="CryptAuthV2DeviceSyncResultCode" expires_after="2024-03-03">
+    enum="CryptAuthV2DeviceSyncResultCode" expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1140,7 +1140,7 @@
 </histogram>
 
 <histogram name="EasyUnlock.AuthEvent.Unlock" enum="EasyUnlockAuthEvent"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1247,7 +1247,7 @@
 </histogram>
 
 <histogram name="InstantTethering.BluetoothDiscoverySessionStarted"
-    enum="BooleanSuccess" expires_after="2024-03-03">
+    enum="BooleanSuccess" expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1256,7 +1256,7 @@
 </histogram>
 
 <histogram name="InstantTethering.BluetoothDiscoverySessionStopped"
-    enum="BooleanSuccess" expires_after="2024-03-03">
+    enum="BooleanSuccess" expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1266,7 +1266,7 @@
 
 <histogram name="InstantTethering.ConnectionToHostResult.Failure"
     enum="InstantTethering_ConnectionToHostResult_Failure"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1285,7 +1285,7 @@
 <histogram
     name="InstantTethering.ConnectionToHostResult.Failure.ClientConnection"
     enum="InstantTethering_ConnectionToHostResult_Failure_ClientConnection"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1305,7 +1305,7 @@
 <histogram
     name="InstantTethering.ConnectionToHostResult.Failure.TetheringTimeout"
     enum="InstantTethering_ConnectionToHostResult_Failure_TetheringTimeout"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1337,7 +1337,7 @@
 <histogram
     name="InstantTethering.ConnectionToHostResult.ProvisioningFailureRate"
     enum="InstantTethering_ConnectionToHostResult_ProvisioningFailureRate"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1357,7 +1357,7 @@
 <histogram
     name="InstantTethering.ConnectionToHostResult.SuccessRate.Background"
     enum="InstantTethering_ConnectionToHostResult_SuccessRate"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1374,7 +1374,7 @@
 </histogram>
 
 <histogram name="InstantTethering.FeatureState"
-    enum="InstantTethering_FeatureState" expires_after="2024-03-03">
+    enum="InstantTethering_FeatureState" expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1390,7 +1390,7 @@
 </histogram>
 
 <histogram name="InstantTethering.HostScanBatchDuration" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1406,7 +1406,7 @@
 </histogram>
 
 <histogram name="InstantTethering.HostScanResult"
-    enum="InstantTethering_HostScanResult" expires_after="2024-03-03">
+    enum="InstantTethering_HostScanResult" expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1424,7 +1424,7 @@
 </histogram>
 
 <histogram name="InstantTethering.HotspotUsageDuration" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1435,7 +1435,7 @@
 </histogram>
 
 <histogram name="InstantTethering.KeepAliveTickle.Result" enum="BooleanSuccess"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1445,7 +1445,7 @@
 </histogram>
 
 <histogram name="InstantTethering.MultiDeviceFeatureState"
-    enum="MultiDevice_FeatureState" expires_after="2024-03-03">
+    enum="MultiDevice_FeatureState" expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1457,7 +1457,7 @@
 
 <histogram name="InstantTethering.NotificationInteractionType"
     enum="InstantTethering_NotificationInteractionType"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1467,7 +1467,7 @@
 </histogram>
 
 <histogram name="InstantTethering.Performance.ConnectTetheringResponseDuration"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1477,7 +1477,7 @@
 </histogram>
 
 <histogram name="InstantTethering.Performance.ConnectToHostDuration.Background"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1488,7 +1488,7 @@
 </histogram>
 
 <histogram name="InstantTethering.Performance.ConnectToHotspotDuration"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1500,7 +1500,7 @@
 
 <histogram
     name="InstantTethering.Performance.DisconnectTetheringRequestDuration"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1510,7 +1510,7 @@
 </histogram>
 
 <histogram name="InstantTethering.Performance.KeepAliveTickleResponseDuration"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1521,7 +1521,7 @@
 
 <histogram
     name="InstantTethering.Performance.TetherAvailabilityResponseDuration"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1531,7 +1531,7 @@
 </histogram>
 
 <histogram name="InstantTethering.SessionCompletionReason"
-    enum="InstantTethering_SessionCompletionReason" expires_after="2024-03-03">
+    enum="InstantTethering_SessionCompletionReason" expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1543,7 +1543,7 @@
 </histogram>
 
 <histogram name="InstantTethering.UserPreference.OnStartup"
-    enum="BooleanEnabled" expires_after="2024-03-03">
+    enum="BooleanEnabled" expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1554,7 +1554,7 @@
 </histogram>
 
 <histogram name="InstantTethering.UserPreference.OnToggle"
-    enum="BooleanEnabled" expires_after="2024-03-03">
+    enum="BooleanEnabled" expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1565,7 +1565,7 @@
 </histogram>
 
 <histogram name="MultiDevice.BetterTogetherSuite.MultiDeviceFeatureState"
-    enum="MultiDevice_FeatureState" expires_after="2024-03-03">
+    enum="MultiDevice_FeatureState" expires_after="2024-05-05">
   <owner>hansberry@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1662,7 +1662,7 @@
 
 <histogram name="MultiDevice.ForgetHostConfirmed"
     enum="MultiDevice_VerifyAndForgetHostConfirmationState"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hansberry@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1671,7 +1671,7 @@
 </histogram>
 
 <histogram name="MultiDevice.PostOOBESetupFlow.PageShown"
-    enum="MultiDevice_PostOOBESetupFlow_Page" expires_after="2024-03-03">
+    enum="MultiDevice_PostOOBESetupFlow_Page" expires_after="2024-05-05">
   <owner>hansberry@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1688,7 +1688,7 @@
 
 <histogram
     name="MultiDevice.SecureChannel.BLE.GattConnectionToAuthentication.EffectiveSuccessRateWithRetries"
-    enum="BooleanSuccess" expires_after="2024-03-03">
+    enum="BooleanSuccess" expires_after="2024-05-05">
   <owner>hansberry@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1701,7 +1701,7 @@
 
 <histogram
     name="MultiDevice.SecureChannel.BLE.Performance.ConnectionToAuthenticationDuration.Background"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>hansberry@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1717,7 +1717,7 @@
 
 <histogram
     name="MultiDevice.SecureChannel.BLE.Performance.ReceiveAdvertisementToConnectionDuration.Background"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>hansberry@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1733,7 +1733,7 @@
 
 <histogram
     name="MultiDevice.SecureChannel.BLE.Performance.StartScanToAuthenticationDuration.Background"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>hansberry@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1750,7 +1750,7 @@
 
 <histogram
     name="MultiDevice.SecureChannel.BLE.Performance.StartScanToConnectionDuration.Background"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>hansberry@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1766,7 +1766,7 @@
 
 <histogram
     name="MultiDevice.SecureChannel.BLE.Performance.StartScanToReceiveAdvertisementDuration.Background"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>hansberry@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1782,7 +1782,7 @@
 
 <histogram
     name="MultiDevice.SecureChannel.BLE.ReceiveAdvertisementToAuthentication.EffectiveSuccessRateWithRetries"
-    enum="BooleanSuccess" expires_after="2024-03-03">
+    enum="BooleanSuccess" expires_after="2024-05-05">
   <owner>hansberry@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1794,7 +1794,7 @@
 
 <histogram
     name="MultiDevice.SecureChannel.BLE.ReceiveAdvertisementToGattConnection.EffectiveSuccessRateWithRetries"
-    enum="BooleanSuccess" expires_after="2024-03-03">
+    enum="BooleanSuccess" expires_after="2024-05-05">
   <owner>hansberry@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1805,7 +1805,7 @@
 </histogram>
 
 <histogram name="MultiDevice.SecureChannel.Nearby.ConnectionMedium"
-    enum="SecureChannelNearbyConnectionMedium" expires_after="2024-03-03">
+    enum="SecureChannelNearbyConnectionMedium" expires_after="2024-05-05">
   <owner>hansenmichael@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1820,7 +1820,7 @@
 
 <histogram name="MultiDevice.SecureChannel.Nearby.ConnectionResult"
     enum="MultiDeviceNearbyConnectionsInitiatorResult"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hansenmichael@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1833,7 +1833,7 @@
 </histogram>
 
 <histogram name="MultiDevice.SecureChannel.Nearby.DisconnectionReason"
-    enum="MultiDeviceNearbyDisconnectionReason" expires_after="2024-03-03">
+    enum="MultiDeviceNearbyDisconnectionReason" expires_after="2024-05-05">
   <owner>hansenmichael@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1848,7 +1848,7 @@
 </histogram>
 
 <histogram name="MultiDevice.SecureChannel.Nearby.EffectiveConnectionResult"
-    enum="BooleanSuccess" expires_after="2024-03-03">
+    enum="BooleanSuccess" expires_after="2024-05-05">
   <owner>hansenmichael@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1864,7 +1864,7 @@
 </histogram>
 
 <histogram name="MultiDevice.SecureChannel.Nearby.FileAction"
-    enum="MultiDeviceNearbyFileAction" expires_after="2024-03-03">
+    enum="MultiDeviceNearbyFileAction" expires_after="2024-05-05">
   <owner>jasonsun@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1875,7 +1875,7 @@
 </histogram>
 
 <histogram name="MultiDevice.SecureChannel.Nearby.FileTransferResult"
-    enum="MultiDeviceNearbyFileTransferResult" expires_after="2024-03-03">
+    enum="MultiDeviceNearbyFileTransferResult" expires_after="2024-05-05">
   <owner>jasonsun@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1886,7 +1886,7 @@
 </histogram>
 
 <histogram name="MultiDevice.SecureChannel.Nearby.MessageAction"
-    enum="MultiDeviceNearbyMessageAction" expires_after="2024-03-03">
+    enum="MultiDeviceNearbyMessageAction" expires_after="2024-05-05">
   <owner>hansenmichael@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1897,7 +1897,7 @@
 </histogram>
 
 <histogram name="MultiDevice.SecureChannel.Nearby.OperationResult.{Function}"
-    enum="NearbyConnectionsStatus" expires_after="2024-03-03">
+    enum="NearbyConnectionsStatus" expires_after="2024-05-05">
   <owner>hansenmichael@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1919,7 +1919,7 @@
 </histogram>
 
 <histogram name="MultiDevice.SecureChannel.Nearby.SendMessageResult"
-    enum="BooleanSuccess" expires_after="2024-03-03">
+    enum="BooleanSuccess" expires_after="2024-05-05">
   <owner>hansenmichael@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1930,7 +1930,7 @@
 </histogram>
 
 <histogram name="MultiDevice.SecureChannel.Nearby.WebRtcUpgradeDuration"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>hansenmichael@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1944,7 +1944,7 @@
 </histogram>
 
 <histogram name="MultiDevice.Setup.HasDuplicateEligibleHostDeviceNames"
-    enum="BooleanDuplicate" expires_after="2024-03-03">
+    enum="BooleanDuplicate" expires_after="2024-05-05">
   <owner>hansenmichael@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1956,7 +1956,7 @@
 </histogram>
 
 <histogram name="MultiDevice.Setup.HostStatus"
-    enum="MultiDevice_Setup_HostStatus" expires_after="2024-03-03">
+    enum="MultiDevice_Setup_HostStatus" expires_after="2024-05-05">
   <owner>hansberry@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -2046,7 +2046,7 @@
 </histogram>
 
 <histogram name="MultiDeviceSetup.OOBE.UserChoice"
-    enum="MultiDeviceSetupOOBEUserChoice" expires_after="2024-03-03">
+    enum="MultiDeviceSetupOOBEUserChoice" expires_after="2024-05-05">
   <owner>hansberry@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <owner>hsuregan@chromium.org</owner>
@@ -2098,7 +2098,7 @@
 </histogram>
 
 <histogram name="ProximityAuth.BleWeaveConnectionResult"
-    enum="ProximityAuth_BleWeaveConnectionResult" expires_after="2024-03-03">
+    enum="ProximityAuth_BleWeaveConnectionResult" expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -2109,7 +2109,7 @@
 
 <histogram name="ProximityAuth.BluetoothGattConnectionResult"
     enum="ProximityAuth_BluetoothGattConnectionResult"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -2125,7 +2125,7 @@
 
 <histogram name="ProximityAuth.BluetoothGattNotifySessionResult"
     enum="ProximityAuth_BluetoothGattServiceOperationResult"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -2141,7 +2141,7 @@
 
 <histogram name="ProximityAuth.BluetoothGattWriteCharacteristicResult"
     enum="ProximityAuth_BluetoothGattServiceOperationResult"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -2175,7 +2175,7 @@
 </histogram>
 
 <histogram name="SmartLock.AuthMethodChoice.Unlock"
-    enum="SmartLockAuthMethodChoice" expires_after="2024-03-03">
+    enum="SmartLockAuthMethodChoice" expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>Records the user's unlock method choice.</summary>
@@ -2192,7 +2192,7 @@
 </histogram>
 
 <histogram name="SmartLock.AuthResult" enum="BooleanSuccess"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -2241,7 +2241,7 @@
 </histogram>
 
 <histogram name="SmartLock.AuthResult.Unlock" enum="BooleanSuccess"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -2272,7 +2272,7 @@
 </histogram>
 
 <histogram name="SmartLock.EnabledState" enum="SmartLockEnabledState"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -2298,7 +2298,7 @@
 </histogram>
 
 <histogram name="SmartLock.FindAndConnectToHostResult.Unlock"
-    enum="SmartLockFindAndConnectToHostResult" expires_after="2024-03-03">
+    enum="SmartLockFindAndConnectToHostResult" expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -2308,7 +2308,7 @@
 </histogram>
 
 <histogram name="SmartLock.FirstStatusToUser" enum="FirstSmartLockStatus"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>cclem@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -2346,7 +2346,7 @@
 </histogram>
 
 <histogram name="SmartLock.GetRemoteStatus.Unlock" enum="BooleanSuccess"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -2367,7 +2367,7 @@
 </histogram>
 
 <histogram name="SmartLock.MultiDeviceFeatureState"
-    enum="MultiDevice_FeatureState" expires_after="2024-03-03">
+    enum="MultiDevice_FeatureState" expires_after="2024-05-05">
   <owner>hansberry@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -2379,7 +2379,7 @@
 
 <histogram
     name="SmartLock.Performance.AuthenticationToReceiveFirstRemoteStatusDuration.Unlock"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
 <!-- Name completed by histogram_suffixes name="SmartLockStatusTypes" -->
 
   <owner>hansberry@chromium.org</owner>
@@ -2402,7 +2402,7 @@
 
 <histogram
     name="SmartLock.Performance.ShowLockScreenToShowFirstStatusToUserDuration.Unlock"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
 <!-- Name completed by histogram_suffixes name="SmartLockStatusTypes" -->
 
   <owner>hansberry@chromium.org</owner>
@@ -2425,7 +2425,7 @@
 
 <histogram
     name="SmartLock.Performance.StartScanToReceiveFirstRemoteStatusDuration.Unlock"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
 <!-- Name completed by histogram_suffixes name="SmartLockStatusTypes" -->
 
   <owner>hansberry@chromium.org</owner>
@@ -2453,7 +2453,7 @@
 </histogram>
 
 <histogram name="SmartLock.Toggle" enum="SmartLockToggle"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>cclem@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/crostini/histograms.xml b/tools/metrics/histograms/metadata/crostini/histograms.xml
index 5d4bbd4..3014327 100644
--- a/tools/metrics/histograms/metadata/crostini/histograms.xml
+++ b/tools/metrics/histograms/metadata/crostini/histograms.xml
@@ -165,28 +165,28 @@
 </histogram>
 
 <histogram name="Crostini.Disk.StatefulReadsDaily" units="KiB"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>drmasquatch@google.com</owner>
   <owner>clumptini@google.com</owner>
   <summary>Crostini stateful KiB read per day. Reported daily.</summary>
 </histogram>
 
 <histogram name="Crostini.Disk.StatefulWritesDaily" units="KiB"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>drmasquatch@google.com</owner>
   <owner>clumptini@google.com</owner>
   <summary>Crostini stateful KiB written per day. Reported daily.</summary>
 </histogram>
 
 <histogram name="Crostini.Disk.SwapReadsDaily" units="KiB"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>drmasquatch@google.com</owner>
   <owner>clumptini@google.com</owner>
   <summary>Crostini swap file KiB read per day. Reported daily.</summary>
 </histogram>
 
 <histogram name="Crostini.Disk.SwapWritesDaily" units="KiB"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>drmasquatch@google.com</owner>
   <owner>clumptini@google.com</owner>
   <summary>Crostini swap file KiB written per day. Reported daily.</summary>
@@ -391,7 +391,7 @@
 </histogram>
 
 <histogram name="Crostini.Setup.Started" enum="BooleanAttempted"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>davidmunro@google.com</owner>
   <owner>clumptini@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/cryptohome/histograms.xml b/tools/metrics/histograms/metadata/cryptohome/histograms.xml
index 29991dd..e4416e636 100644
--- a/tools/metrics/histograms/metadata/cryptohome/histograms.xml
+++ b/tools/metrics/histograms/metadata/cryptohome/histograms.xml
@@ -735,7 +735,7 @@
 </histogram>
 
 <histogram name="Cryptohome.{AuthBlockType}.CredentialRevocationResult"
-    enum="CryptohomeLECredError" expires_after="2024-03-03">
+    enum="CryptohomeLECredError" expires_after="2024-05-05">
   <owner>anastasiian@chromium.org</owner>
   <owner>cros-lurs@google.com</owner>
   <summary>
@@ -747,7 +747,7 @@
 </histogram>
 
 <histogram name="Cryptohome.{AuthBlockType}.PrepareForRemovalResult"
-    enum="CryptohomeCryptoError" expires_after="2024-03-03">
+    enum="CryptohomeCryptoError" expires_after="2024-05-05">
   <owner>anastasiian@chromium.org</owner>
   <owner>cros-lurs@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/custom_tabs/histograms.xml b/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
index a89b63a..8450a36d 100644
--- a/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
+++ b/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
@@ -894,7 +894,7 @@
 </histogram>
 
 <histogram name="TrustedWebActivity.SplashScreenShown" enum="Boolean"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>peconn@chromium.org</owner>
   <owner>peter@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/dev/histograms.xml b/tools/metrics/histograms/metadata/dev/histograms.xml
index a4daa7af..d606c33 100644
--- a/tools/metrics/histograms/metadata/dev/histograms.xml
+++ b/tools/metrics/histograms/metadata/dev/histograms.xml
@@ -50,7 +50,7 @@
 </histogram>
 
 <histogram name="DevTools.BadgeActivated" enum="DevToolsBadgeActivated"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>ergunsh@chromium.org</owner>
   <owner>changhaohan@chromium.org</owner>
   <owner>bmeurer@chromium.org</owner>
@@ -69,7 +69,7 @@
 
 <histogram name="DevTools.BreakpointsRestoredFromStorageCount"
     enum="DevToolsBreakpointsRestoredFromStorageCount"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>bmeurer@chromium.org</owner>
   <owner>kimanh@chromium.org</owner>
   <summary>
@@ -201,7 +201,7 @@
 </histogram>
 
 <histogram name="DevTools.Elements.SidebarTabShown"
-    enum="DevToolsElementsSidebarTab" expires_after="2024-03-03">
+    enum="DevToolsElementsSidebarTab" expires_after="2024-05-05">
   <owner>bmeurer@chromium.org</owner>
   <owner>changhaohan@chromium.org</owner>
   <summary>
@@ -533,14 +533,14 @@
 </histogram>
 
 <histogram name="DevTools.SidebarPaneShown" enum="DevToolsSidebarPane"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>bmeurer@chromium.org</owner>
   <owner>changhaohan@chromium.org</owner>
   <summary>Specified DevTools sidebar pane was shown.</summary>
 </histogram>
 
 <histogram name="DevTools.Sources.SidebarTabShown"
-    enum="DevToolsSourcesSidebarTab" expires_after="2024-03-03">
+    enum="DevToolsSourcesSidebarTab" expires_after="2024-05-05">
   <owner>bmeurer@chromium.org</owner>
   <owner>kimanh@chromium.org</owner>
   <summary>
@@ -549,7 +549,7 @@
 </histogram>
 
 <histogram name="DevTools.SourcesPanelFileDebugged" enum="DevToolsMediaType"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>bmeurer@chromium.org</owner>
   <owner>szuend@chromium.org</owner>
   <summary>
@@ -560,7 +560,7 @@
 </histogram>
 
 <histogram name="DevTools.SourcesPanelFileOpened" enum="DevToolsMediaType"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>yangguo@chromium.org</owner>
   <owner>bmeurer@chromium.org</owner>
   <summary>
@@ -569,7 +569,7 @@
 </histogram>
 
 <histogram name="DevTools.StyleTextCopied" enum="DevToolsStyleTextCopied"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>changhaohan@chromium.org</owner>
   <owner>bmeurer@chromium.org</owner>
   <owner>yangguo@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/download/histograms.xml b/tools/metrics/histograms/metadata/download/histograms.xml
index eb7416b..e720485 100644
--- a/tools/metrics/histograms/metadata/download/histograms.xml
+++ b/tools/metrics/histograms/metadata/download/histograms.xml
@@ -407,7 +407,7 @@
 </histogram>
 
 <histogram name="Download.InsecureBlocking.Totals"
-    enum="InsecureDownloadSecurityStatus" expires_after="2024-02-11">
+    enum="InsecureDownloadSecurityStatus" expires_after="2024-05-05">
   <owner>jdeblasio@chromium.org</owner>
   <owner>estark@chromium.org</owner>
   <owner>cthomp@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/enterprise/histograms.xml b/tools/metrics/histograms/metadata/enterprise/histograms.xml
index a3f233a..ccd7326 100644
--- a/tools/metrics/histograms/metadata/enterprise/histograms.xml
+++ b/tools/metrics/histograms/metadata/enterprise/histograms.xml
@@ -1917,7 +1917,7 @@
 </histogram>
 
 <histogram name="Enterprise.EnrollmentForcedInitialAttestationBased"
-    enum="EnterpriseEnrollmentType" expires_after="2024-02-04">
+    enum="EnterpriseEnrollmentType" expires_after="2024-05-05">
   <owner>asumaneev@google.com</owner>
   <owner>sergiyb@chromium.org</owner>
   <owner>chromeos-commercial-remote-management@google.com</owner>
@@ -2534,7 +2534,7 @@
 </histogram>
 
 <histogram name="Enterprise.PolicyUpdatePeriod.MachineLevelUser" units="days"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>zmin@chromium.org</owner>
   <owner>pastarmovj@chromium.org</owner>
   <summary>
@@ -3172,7 +3172,7 @@
 </histogram>
 
 <histogram name="EnterpriseCheck.IsEnterpriseUser" enum="BooleanEnabled"
-    expires_after="2024-02-04">
+    expires_after="2024-05-05">
   <owner>pastarmovj@chromium.org</owner>
   <owner>rogerta@chromium.org</owner>
   <owner>zmin@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/extensions/histograms.xml b/tools/metrics/histograms/metadata/extensions/histograms.xml
index 07f68b1..c57ca87a 100644
--- a/tools/metrics/histograms/metadata/extensions/histograms.xml
+++ b/tools/metrics/histograms/metadata/extensions/histograms.xml
@@ -1604,7 +1604,7 @@
 </histogram>
 
 <histogram name="Extensions.ExtensionsWithPageActions" units="units"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>extensions-core@chromium.org</owner>
   <summary>
@@ -2549,7 +2549,7 @@
 </histogram>
 
 <histogram name="Extensions.HomepageOverrides2" units="units"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>kelvinjiang@chromium.org</owner>
   <summary>
@@ -3446,7 +3446,7 @@
 </histogram>
 
 <histogram name="Extensions.LoadTheme2" units="units"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>extensions-core@chromium.org</owner>
   <summary>
@@ -3738,7 +3738,7 @@
 </histogram>
 
 <histogram name="Extensions.Navigation.Scheme" enum="ExtensionNavigationScheme"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jkokatsu@google.com</owner>
   <owner>extensions-core@chromium.org</owner>
   <summary>
@@ -3781,7 +3781,7 @@
 </histogram>
 
 <histogram name="Extensions.NewTabPageOverrides2" units="units"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>rdevlin.cronin@chromium.org</owner>
   <owner>kelvinjiang@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/families/histograms.xml b/tools/metrics/histograms/metadata/families/histograms.xml
index 871f18c..9717eaa 100644
--- a/tools/metrics/histograms/metadata/families/histograms.xml
+++ b/tools/metrics/histograms/metadata/families/histograms.xml
@@ -257,7 +257,7 @@
 </histogram>
 
 <histogram name="FamilyLinkUser.ClassifyUrlRequest.AuthError"
-    enum="GoogleServiceAuthError" expires_after="2024-03-03">
+    enum="GoogleServiceAuthError" expires_after="2024-05-05">
   <owner>tju@google.com</owner>
   <owner>chrome-kids-eng@google.com</owner>
   <summary>
@@ -291,7 +291,7 @@
 </histogram>
 
 <histogram name="FamilyLinkUser.ClassifyUrlRequest.ParsingResult"
-    enum="KidsChromeManagementClientParsingError" expires_after="2024-03-03">
+    enum="KidsChromeManagementClientParsingError" expires_after="2024-05-05">
   <owner>tju@google.com</owner>
   <owner>chrome-kids-eng@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/fastpair/histograms.xml b/tools/metrics/histograms/metadata/fastpair/histograms.xml
index 6bb0bfeb..2218c07 100644
--- a/tools/metrics/histograms/metadata/fastpair/histograms.xml
+++ b/tools/metrics/histograms/metadata/fastpair/histograms.xml
@@ -23,7 +23,7 @@
 <histograms>
 
 <histogram name="FastPair.CreateBond.Latency" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jackshira@google.com</owner>
   <owner>dclasson@google.com</owner>
   <owner>brandosocarras@google.com</owner>
@@ -36,7 +36,7 @@
 </histogram>
 
 <histogram name="FastPair.GattConnection" enum="FastPairGattConnectionSteps"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jackshira@google.com</owner>
   <owner>dclasson@google.com</owner>
   <owner>brandosocarras@google.com</owner>
@@ -62,7 +62,7 @@
 </histogram>
 
 <histogram name="FastPair.Handshake.AttemptCount" units="count"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jackshira@google.com</owner>
   <owner>dclasson@google.com</owner>
   <owner>brandosocarras@google.com</owner>
@@ -75,7 +75,7 @@
 </histogram>
 
 <histogram name="FastPair.Handshake.EffectiveSuccessRate" enum="BooleanSuccess"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jackshira@google.com</owner>
   <owner>dclasson@google.com</owner>
   <owner>brandosocarras@google.com</owner>
@@ -88,7 +88,7 @@
 </histogram>
 
 <histogram name="FastPair.InitialPairing"
-    enum="FastPairInitialSuccessFunnelEvent" expires_after="2024-03-03">
+    enum="FastPairInitialSuccessFunnelEvent" expires_after="2024-05-05">
   <owner>jackshira@google.com</owner>
   <owner>dclasson@google.com</owner>
   <owner>brandosocarras@google.com</owner>
@@ -155,7 +155,7 @@
 </histogram>
 
 <histogram name="FastPair.RetroactivePairing"
-    enum="FastPairRetroactiveSuccessFunnelEvent" expires_after="2024-03-03">
+    enum="FastPairRetroactiveSuccessFunnelEvent" expires_after="2024-05-05">
   <owner>jackshira@google.com</owner>
   <owner>dclasson@google.com</owner>
   <owner>brandosocarras@google.com</owner>
@@ -170,7 +170,7 @@
 </histogram>
 
 <histogram name="FastPair.SubsequentPairing"
-    enum="FastPairSubsequentSuccessFunnelEvent" expires_after="2024-03-03">
+    enum="FastPairSubsequentSuccessFunnelEvent" expires_after="2024-05-05">
   <owner>jackshira@google.com</owner>
   <owner>dclasson@google.com</owner>
   <owner>brandosocarras@google.com</owner>
@@ -183,7 +183,7 @@
 </histogram>
 
 <histogram name="FastPair.{FastPairPairingProtocol}.Pairing"
-    enum="FastPairProtocolPairingSteps" expires_after="2024-03-03">
+    enum="FastPairProtocolPairingSteps" expires_after="2024-05-05">
   <owner>jackshira@google.com</owner>
   <owner>dclasson@google.com</owner>
   <owner>brandosocarras@google.com</owner>
@@ -203,7 +203,7 @@
 </histogram>
 
 <histogram name="FastPair.{PairingScenario}.Initialization"
-    enum="FastPairInitializePairingProcessEvent" expires_after="2024-03-03">
+    enum="FastPairInitializePairingProcessEvent" expires_after="2024-05-05">
   <owner>jackshira@google.com</owner>
   <owner>dclasson@google.com</owner>
   <owner>brandosocarras@google.com</owner>
@@ -241,7 +241,7 @@
 </histogram>
 
 <histogram name="FastPair.{PairingScenario}.Initialization.FailureReason"
-    enum="FastPairPairFailure" expires_after="2024-03-03">
+    enum="FastPairPairFailure" expires_after="2024-05-05">
   <owner>jackshira@google.com</owner>
   <owner>dclasson@google.com</owner>
   <owner>brandosocarras@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/feature_engagement/histograms.xml b/tools/metrics/histograms/metadata/feature_engagement/histograms.xml
index ba0d083..664d6678 100644
--- a/tools/metrics/histograms/metadata/feature_engagement/histograms.xml
+++ b/tools/metrics/histograms/metadata/feature_engagement/histograms.xml
@@ -613,7 +613,7 @@
 </histogram>
 
 <histogram name="Tutorial{TutorialID}.Completion" enum="BooleanSuccess"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>dpenning@chromium.org</owner>
   <owner>dfried@chromium.org</owner>
   <summary>
@@ -624,7 +624,7 @@
 </histogram>
 
 <histogram name="Tutorial{TutorialID}.IPHLinkClicked" enum="BooleanSuccess"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>dpenning@chromium.org</owner>
   <owner>dfried@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/file/histograms.xml b/tools/metrics/histograms/metadata/file/histograms.xml
index c7d5555..25cee193 100644
--- a/tools/metrics/histograms/metadata/file/histograms.xml
+++ b/tools/metrics/histograms/metadata/file/histograms.xml
@@ -328,7 +328,7 @@
 </histogram>
 
 <histogram name="FileBrowser.DownloadDestination.IsGoogleDrive.Started"
-    enum="BooleanEnabled" expires_after="2024-03-03">
+    enum="BooleanEnabled" expires_after="2024-05-05">
   <owner>simmonsjosh@google.com</owner>
   <owner>src/ui/file_manager/OWNERS</owner>
   <summary>
@@ -830,7 +830,7 @@
 </histogram>
 
 <histogram name="FileBrowser.Location.OnEntryExpandedOrCollapsed.TopLevel"
-    enum="FileManagerRootType" expires_after="2024-03-03">
+    enum="FileManagerRootType" expires_after="2024-05-05">
   <owner>simmonsjosh@google.com</owner>
   <owner>src/ui/file_manager/OWNERS</owner>
   <summary>
@@ -1707,7 +1707,7 @@
 </histogram>
 
 <histogram name="FileBrowser.ViewingFileType.Offline" enum="ViewFileType"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>simmonsjosh@google.com</owner>
   <owner>src/ui/file_manager/OWNERS</owner>
   <summary>
@@ -1718,7 +1718,7 @@
 </histogram>
 
 <histogram name="FileBrowser.ViewingFileType.Online" enum="ViewFileType"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>simmonsjosh@google.com</owner>
   <owner>src/ui/file_manager/OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/fingerprint/histograms.xml b/tools/metrics/histograms/metadata/fingerprint/histograms.xml
index d11e52b7..ffaa9ab3 100644
--- a/tools/metrics/histograms/metadata/fingerprint/histograms.xml
+++ b/tools/metrics/histograms/metadata/fingerprint/histograms.xml
@@ -36,7 +36,7 @@
 </histogram>
 
 <histogram name="Fingerprint.Auth.ScanResult" enum="FingerprintScanResult"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>emaamari@google.com</owner>
   <owner>tomhughes@chromium.org</owner>
   <owner>cros-lurs@google.com</owner>
@@ -90,7 +90,7 @@
 </histogram>
 
 <histogram name="Fingerprint.FingerprintPowerButtonRace" units="units"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>emaamari@google.com</owner>
   <owner>chromeos-commercial-identity@google.com</owner>
   <owner>chromeos-fingerprint@google.com</owner>
@@ -115,7 +115,7 @@
 </histogram>
 
 <histogram name="Fingerprint.SensorError.BadHwid" enum="BooleanError"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>fsammoura@google.com</owner>
   <owner>chromeos-fingerprint@google.com</owner>
   <summary>
@@ -125,7 +125,7 @@
 </histogram>
 
 <histogram name="Fingerprint.SensorError.InitializationFailure"
-    enum="BooleanError" expires_after="2024-03-03">
+    enum="BooleanError" expires_after="2024-05-05">
   <owner>fsammoura@google.com</owner>
   <owner>chromeos-fingerprint@google.com</owner>
   <summary>
@@ -135,7 +135,7 @@
 </histogram>
 
 <histogram name="Fingerprint.SensorError.NoIrq" enum="BooleanError"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>fsammoura@google.com</owner>
   <owner>chromeos-fingerprint@google.com</owner>
   <summary>
@@ -145,7 +145,7 @@
 </histogram>
 
 <histogram name="Fingerprint.SensorError.SpiCommunication" enum="BooleanError"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>fsammoura@google.com</owner>
   <owner>chromeos-fingerprint@google.com</owner>
   <summary>
@@ -165,7 +165,7 @@
 </histogram>
 
 <histogram name="Fingerprint.Session.RetrievePrimarySessionResult"
-    enum="FingerprintRetrievePrimarySessionResult" expires_after="2024-03-03">
+    enum="FingerprintRetrievePrimarySessionResult" expires_after="2024-05-05">
   <owner>patrykd@google.com</owner>
   <owner>chromeos-fingerprint@google.com</owner>
   <summary>
@@ -186,7 +186,7 @@
 </histogram>
 
 <histogram name="Fingerprint.Unlock.AttemptsCountBeforeSuccess" units="count"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>emaamari@google.com</owner>
   <owner>cros-lurs@google.com</owner>
   <summary>
@@ -201,7 +201,7 @@
 </histogram>
 
 <histogram name="Fingerprint.Unlock.AuthSuccessful" enum="BooleanSuccess"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>emaamari@google.com</owner>
   <owner>cros-lurs@google.com</owner>
   <summary>
@@ -215,7 +215,7 @@
 </histogram>
 
 <histogram name="Fingerprint.Unlock.EnrolledFingerCount" units="count"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>tomhughes@chromium.org</owner>
   <owner>chromeos-fingerprint@google.com</owner>
   <summary>
@@ -242,7 +242,7 @@
 </histogram>
 
 <histogram name="Fingerprint.Unlock.MatchIgnoredDueToPowerButtonPress"
-    enum="BooleanIgnored" expires_after="2024-03-03">
+    enum="BooleanIgnored" expires_after="2024-05-05">
   <owner>ravisadineni@chromium.org</owner>
   <owner>chromeos-fingerprint@google.com</owner>
   <summary>
@@ -289,7 +289,7 @@
 </histogram>
 
 <histogram name="Fingerprint.Unlock.RecentAttemptsCountBeforeSuccess"
-    units="attempts" expires_after="2024-03-03">
+    units="attempts" expires_after="2024-05-05">
   <owner>hesling@chromium.org</owner>
   <owner>chromeos-fingerprint@google.com</owner>
   <summary>
@@ -319,7 +319,7 @@
 </histogram>
 
 <histogram name="Fingerprint.Unlock.Result" enum="FingerprintUnlockResult"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>emaamari@google.com</owner>
   <owner>tomhughes@chromium.org</owner>
   <owner>cros-lurs@google.com</owner>
@@ -331,7 +331,7 @@
 </histogram>
 
 <histogram name="Fingerprint.Unlock.{Outcome}.Duration.{Interval}" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>bobbycasey@google.com</owner>
   <owner>chromeos-fingerprint@google.com</owner>
   <summary>
@@ -351,7 +351,7 @@
 </histogram>
 
 <histogram name="Fingerprint.UnlockEnabled" enum="BooleanEnabled"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>tomhughes@chromium.org</owner>
   <owner>chromeos-fingerprint@google.com</owner>
   <summary>
@@ -370,7 +370,7 @@
 </histogram>
 
 <histogram name="Fingerprint.Updater.Reason" enum="FingerprintUpdaterReason"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>tomhughes@chromium.org</owner>
   <owner>hesling@chromium.org</owner>
   <owner>chromeos-fingerprint@google.com</owner>
@@ -380,7 +380,7 @@
 </histogram>
 
 <histogram name="Fingerprint.Updater.Status" enum="FingerprintUpdaterStatus"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>tomhughes@chromium.org</owner>
   <owner>hesling@chromium.org</owner>
   <owner>chromeos-fingerprint@google.com</owner>
@@ -403,7 +403,7 @@
 </histogram>
 
 <histogram name="Fingerprint.{ContextFunction}" enum="FingerprintSensorMode"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>tomhughes@chromium.org</owner>
   <owner>chromeos-fingerprint@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/geolocation/enums.xml b/tools/metrics/histograms/metadata/geolocation/enums.xml
new file mode 100644
index 0000000..a85e365
--- /dev/null
+++ b/tools/metrics/histograms/metadata/geolocation/enums.xml
@@ -0,0 +1,124 @@
+<!--
+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.
+-->
+
+<!--
+
+This file describes the enumerations referenced by entries in histograms.xml for
+this directory. Some enums may instead be listed in the central enums.xml file
+at src/tools/metrics/histograms/enums.xml when multiple files use them.
+
+For best practices on writing enumerations descriptions, see
+https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md#Enum-Histograms
+
+Please follow the instructions in the OWNERS file in this directory to find a
+reviewer. If no OWNERS file exists, please consider signing up at
+go/reviewing-metrics (Googlers only), as all subdirectories are expected to
+have an OWNERS file. As a last resort you can send the CL to
+chromium-metrics-reviews@google.com.
+-->
+
+<histogram-configuration>
+
+<!-- Enum types -->
+
+<enums>
+
+<enum name="AndroidLocationPermissionState">
+  <int value="0" label="NoAccess">No location permissions are granted.</int>
+  <int value="1" label="AccessCoarse">
+    Permission to access approximate location (ACCESS_COARSE_LOCATION).
+  </int>
+  <int value="2" label="AccessFine">
+    Permission to access precise location (ACCESS_FINE_LOCATION).
+  </int>
+</enum>
+
+<enum name="GeolocationAuthorizationAction">
+  <int value="0" label="Location authorized"/>
+  <int value="1" label="Location permanently denied (Don't Allow)"/>
+  <int value="2" label="Location denied at this prompt (Not Now)"/>
+</enum>
+
+<enum name="GeolocationHeaderPermissionState">
+  <int value="0" label="Location mode unknown"/>
+  <int value="1" label="High acc., app allowed, domain allowed, location sent"/>
+  <int value="2"
+      label="High acc., app allowed, domain allowed, location not sent"/>
+  <int value="3" label="High acc., app allowed, domain prompt, location sent"/>
+  <int value="4"
+      label="High acc., app allowed, domain prompt, location not sent"/>
+  <int value="5" label="High acc., app allowed, domain denied"/>
+  <int value="6" label="High acc., app prompt, domain allowed"/>
+  <int value="7" label="High acc., app prompt, domain prompt"/>
+  <int value="8" label="High acc., app prompt, domain denied"/>
+  <int value="9" label="High acc., app denied, domain allowed"/>
+  <int value="10" label="High acc., app denied, domain prompt"/>
+  <int value="11" label="High acc., app denied, domain denied"/>
+  <int value="12"
+      label="Battery sav., app allowed, domain allowed, location sent"/>
+  <int value="13"
+      label="Battery sav., app allowed, domain allowed, location not sent"/>
+  <int value="14"
+      label="Battery sav., app allowed, domain prompt, location sent"/>
+  <int value="15"
+      label="Battery sav., app allowed, domain prompt, location not sent"/>
+  <int value="16" label="Battery sav., app allowed, domain denied"/>
+  <int value="17" label="Battery sav., app prompt, domain allowed"/>
+  <int value="18" label="Battery sav., app prompt, domain prompt"/>
+  <int value="19" label="Battery sav., app prompt, domain denied"/>
+  <int value="20" label="Battery sav., app denied, domain allowed"/>
+  <int value="21" label="Battery sav., app denied, domain prompt"/>
+  <int value="22" label="Battery sav., app denied, domain denied"/>
+  <int value="23" label="GPS only, app allowed, domain allowed, location sent"/>
+  <int value="24"
+      label="GPS only, app allowed, domain allowed, location not sent"/>
+  <int value="25" label="GPS only, app allowed, domain prompt, location sent"/>
+  <int value="26"
+      label="GPS only, app allowed, domain prompt, location not sent"/>
+  <int value="27" label="GPS only, app allowed, domain denied"/>
+  <int value="28" label="GPS only, app prompt, domain allowed"/>
+  <int value="29" label="GPS only, app prompt, domain prompt"/>
+  <int value="30" label="GPS only, app prompt, domain denied"/>
+  <int value="31" label="GPS only, app denied, domain allowed"/>
+  <int value="32" label="GPS only, app denied, domain prompt"/>
+  <int value="33" label="GPS only, app denied, domain denied"/>
+  <int value="34" label="Location off, app allowed, domain allowed"/>
+  <int value="35" label="Location off, app allowed, domain prompt"/>
+  <int value="36" label="Location off, app allowed, domain denied"/>
+  <int value="37" label="Location off, app prompt, domain allowed"/>
+  <int value="38" label="Location off, app prompt, domain prompt"/>
+  <int value="39" label="Location off, app prompt, domain denied"/>
+  <int value="40" label="Location off, app denied, domain allowed"/>
+  <int value="41" label="Location off, app denied, domain prompt"/>
+  <int value="42" label="Location off, app denied, domain denied"/>
+  <int value="43" label="Unsuitable URL"/>
+  <int value="44" label="Not using HTTPS"/>
+</enum>
+
+<enum name="GeolocationHeaderSentOrNot">
+  <int value="0" label="Location disabled for Google domain"/>
+  <int value="1" label="Location preference not set for Google domain"/>
+  <int value="2" label="Location not available"/>
+  <int value="3" label="Location stale"/>
+  <int value="4" label="Header sent"/>
+  <int value="5" label="Location disabled for Chrome app"/>
+  <int value="6" label="iOS: Location disabled for Omnibox query"/>
+  <int value="7" label="Google domain does not accept locations"/>
+</enum>
+
+<enum name="NetworkLocationRequestEvent">
+  <int value="0" label="REQUEST_START"/>
+  <int value="1" label="REQUEST_CANCEL"/>
+  <int value="2" label="RESPONSE_SUCCESS"/>
+  <int value="3" label="RESPONSE_NOT_OK"/>
+  <int value="4" label="RESPONSE_EMPTY"/>
+  <int value="5" label="RESPONSE_MALFORMED"/>
+  <int value="6" label="RESPONSE_INVALID_FIX"/>
+</enum>
+
+</enums>
+
+</histogram-configuration>
diff --git a/tools/metrics/histograms/metadata/geolocation/histograms.xml b/tools/metrics/histograms/metadata/geolocation/histograms.xml
index 0d26a11..09e461a 100644
--- a/tools/metrics/histograms/metadata/geolocation/histograms.xml
+++ b/tools/metrics/histograms/metadata/geolocation/histograms.xml
@@ -118,7 +118,7 @@
 </histogram>
 
 <histogram name="Geolocation.NetworkLocationRequest.RequestInterval"
-    units="mins" expires_after="2024-03-03">
+    units="mins" expires_after="2024-05-05">
   <owner>alvinji@chromium.org</owner>
   <owner>device-dev@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/gpu/histograms.xml b/tools/metrics/histograms/metadata/gpu/histograms.xml
index eedc75d..493483bf 100644
--- a/tools/metrics/histograms/metadata/gpu/histograms.xml
+++ b/tools/metrics/histograms/metadata/gpu/histograms.xml
@@ -615,7 +615,7 @@
 </histogram>
 
 <histogram name="GPU.DirectComposition.HardwareOverlaysSupported"
-    enum="BooleanOverlaySupported" expires_after="2024-03-03">
+    enum="BooleanOverlaySupported" expires_after="2024-05-05">
   <owner>magchen@chromium.org</owner>
   <owner>graphics-dev@chromium.org</owner>
   <summary>
@@ -1113,7 +1113,7 @@
 </histogram>
 
 <histogram name="GPU.Nvidia{Extension}.{State}.SetStreamExt" enum="Hresult"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>magchen@chromium.org</owner>
   <owner>zmo@chromium.org</owner>
   <owner>graphics-dev@chromium.org</owner>
@@ -1417,7 +1417,7 @@
 </histogram>
 
 <histogram name="GPU.SupportsDX12" enum="BooleanSupported"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>magchen@chromium.org</owner>
   <owner>zmo@chromium.org</owner>
   <summary>
@@ -1477,7 +1477,7 @@
 </histogram>
 
 <histogram name="GPU.VideoProcessorBlt.{Extension}.{State}" enum="Hresult"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>magchen@chromium.org</owner>
   <owner>zmo@chromium.org</owner>
   <owner>graphics-dev@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/holding_space/histograms.xml b/tools/metrics/histograms/metadata/holding_space/histograms.xml
index 6a2c050a..31ce9e0 100644
--- a/tools/metrics/histograms/metadata/holding_space/histograms.xml
+++ b/tools/metrics/histograms/metadata/holding_space/histograms.xml
@@ -98,7 +98,7 @@
 </histogram>
 
 <histogram name="HoldingSpace.Downloads.Action.All"
-    enum="HoldingSpaceDownloadsAction" expires_after="2024-03-03">
+    enum="HoldingSpaceDownloadsAction" expires_after="2024-05-05">
   <owner>dmblack@google.com</owner>
   <owner>gzadina@google.com</owner>
   <summary>
@@ -118,7 +118,7 @@
 </histogram>
 
 <histogram name="HoldingSpace.Item.Action.All" enum="HoldingSpaceItemAction"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>dmblack@google.com</owner>
   <owner>gzadina@google.com</owner>
   <summary>
@@ -128,7 +128,7 @@
 </histogram>
 
 <histogram name="HoldingSpace.Item.Action.{action}" enum="HoldingSpaceItemType"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>dmblack@google.com</owner>
   <owner>gzadina@google.com</owner>
   <summary>
@@ -139,7 +139,7 @@
 </histogram>
 
 <histogram name="HoldingSpace.Item.Action.{action}.Extension"
-    enum="HoldingSpaceExtension" expires_after="2024-03-03">
+    enum="HoldingSpaceExtension" expires_after="2024-05-05">
   <owner>dmblack@google.com</owner>
   <owner>gzadina@google.com</owner>
   <summary>
@@ -150,7 +150,7 @@
 </histogram>
 
 <histogram name="HoldingSpace.Item.Action.{action}.FileSystemType"
-    enum="HoldingSpaceFileSystemType" expires_after="2024-03-03">
+    enum="HoldingSpaceFileSystemType" expires_after="2024-05-05">
   <owner>dmblack@google.com</owner>
   <owner>gzadina@google.com</owner>
   <summary>
@@ -161,7 +161,7 @@
 </histogram>
 
 <histogram name="HoldingSpace.Item.Count.{type}" units="items"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>dmblack@google.com</owner>
   <owner>gzadina@google.com</owner>
   <summary>
@@ -202,7 +202,7 @@
 </histogram>
 
 <histogram name="HoldingSpace.Item.TotalCount.{type}" units="items"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>dmblack@google.com</owner>
   <owner>gzadina@google.com</owner>
   <summary>
@@ -214,7 +214,7 @@
 </histogram>
 
 <histogram name="HoldingSpace.Pod.Action.All" enum="HoldingSpacePodAction"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>dmblack@google.com</owner>
   <owner>gzadina@google.com</owner>
   <summary>
@@ -265,7 +265,7 @@
 </histogram>
 
 <histogram name="HoldingSpace.UserPreferences.PreviewsEnabled"
-    enum="BooleanEnabled" expires_after="2024-03-03">
+    enum="BooleanEnabled" expires_after="2024-05-05">
   <owner>dmblack@google.com</owner>
   <owner>gzadina@google.com</owner>
   <summary>
@@ -275,7 +275,7 @@
 </histogram>
 
 <histogram name="HoldingSpace.UserPreferences.SuggestionsExpanded"
-    enum="BooleanExpanded" expires_after="2024-03-03">
+    enum="BooleanExpanded" expires_after="2024-05-05">
   <owner>dmblack@google.com</owner>
   <owner>gzadina@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/input/histograms.xml b/tools/metrics/histograms/metadata/input/histograms.xml
index 080072a..add4e42 100644
--- a/tools/metrics/histograms/metadata/input/histograms.xml
+++ b/tools/metrics/histograms/metadata/input/histograms.xml
@@ -1260,7 +1260,7 @@
 </histogram>
 
 <histogram name="InputMethod.PhysicalKeyboard.KeyboardShortcut"
-    enum="PhysicalKeyboardShortcut" expires_after="2024-03-03">
+    enum="PhysicalKeyboardShortcut" expires_after="2024-05-05">
   <owner>wbjacksonjr@chromium.org</owner>
   <owner>embedded-experience@google.com</owner>
   <summary>
@@ -1439,7 +1439,7 @@
 </histogram>
 
 <histogram name="InputMethod.StylusHandwriting.Gesture"
-    enum="StylusHandwritingGesture" expires_after="2024-03-01">
+    enum="StylusHandwritingGesture" expires_after="2024-05-05">
   <owner>peconn@chromium.org</owner>
   <owner>embedded-experience@google.com</owner>
   <summary>
@@ -1470,7 +1470,7 @@
 </histogram>
 
 <histogram name="InputMethod.StylusHandwriting.Triggered"
-    enum="StylusHandwritingApi" expires_after="2024-03-01">
+    enum="StylusHandwritingApi" expires_after="2024-05-05">
   <owner>peconn@chromium.org</owner>
   <owner>embedded-experience@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/installer/histograms.xml b/tools/metrics/histograms/metadata/installer/histograms.xml
index 163b539..a3d5184a 100644
--- a/tools/metrics/histograms/metadata/installer/histograms.xml
+++ b/tools/metrics/histograms/metadata/installer/histograms.xml
@@ -70,7 +70,7 @@
 </histogram>
 
 <histogram name="Installer.Postinstall.EfiBootEntryFailedLoad" units="entries"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>tbrandston@google.com</owner>
   <owner>chromeos-flex-eng@google.com</owner>
   <summary>
@@ -136,7 +136,7 @@
 </histogram>
 
 <histogram name="Installer.Postinstall.NonChromebookBiosSuccess.{BiosType}"
-    enum="BooleanSuccess" expires_after="2024-03-01">
+    enum="BooleanSuccess" expires_after="2024-05-05">
   <owner>tbrandston@google.com</owner>
   <owner>chromeos-flex-eng@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/ios/histograms.xml b/tools/metrics/histograms/metadata/ios/histograms.xml
index c25b605b..05939c47 100644
--- a/tools/metrics/histograms/metadata/ios/histograms.xml
+++ b/tools/metrics/histograms/metadata/ios/histograms.xml
@@ -815,7 +815,7 @@
 </histogram>
 
 <histogram name="IOS.ExperienceKitCalendar.TextClassifierModelAvailable"
-    enum="BooleanAvailable" expires_after="2024-02-11">
+    enum="BooleanAvailable" expires_after="2024-05-05">
   <owner>rajendrant@chromium.org</owner>
   <owner>sophiechang@chromium.org</owner>
   <summary>
@@ -2117,7 +2117,7 @@
 </histogram>
 
 <histogram name="IOS.PageLoadedSnapshotResult" enum="PageLoadedSnapshotResult"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>edchin@chromium.org</owner>
   <owner>justincohen@chromium.org</owner>
   <summary>
@@ -3475,7 +3475,7 @@
 
 <histogram
     name="IOS.TextSelection.EntityDetection.TFLiteModelEvaluationDuration"
-    units="ms" expires_after="2024-02-11">
+    units="ms" expires_after="2024-05-05">
   <owner>rajendrant@chromium.org</owner>
   <owner>sophiechang@chromium.org</owner>
   <summary>
@@ -3635,7 +3635,7 @@
 </histogram>
 
 <histogram name="IOS.Web.ErrorPagePresentationFailed"
-    enum="IOSErrorPagePresentationFailed" expires_after="2024-03-01">
+    enum="IOSErrorPagePresentationFailed" expires_after="2024-05-05">
   <owner>ajuma@chromium.org</owner>
   <owner>michaeldo@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml
index 098ebe4..ac2fd45 100644
--- a/tools/metrics/histograms/metadata/media/histograms.xml
+++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -386,7 +386,7 @@
 </histogram>
 
 <histogram name="Media.Audible.ConcurrentTabsTime" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>evliu@google.com</owner>
   <owner>media-dev-uma@chromium.org</owner>
   <summary>
@@ -5124,7 +5124,7 @@
 </histogram>
 
 <histogram name="Media.Session.Play" enum="MediaSessionActionSource"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>steimel@chromium.org</owner>
   <owner>media-dev-uma@chromium.org</owner>
   <summary>
@@ -5546,7 +5546,7 @@
 </histogram>
 
 <histogram name="Media.VideoCapture.AspectRatio" units="%"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>mcasas@chromium.org</owner>
   <owner>jophba@chromium.org</owner>
   <summary>
@@ -5680,7 +5680,7 @@
 </histogram>
 
 <histogram name="Media.VideoCapture.FrameRate" units="fps"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>mcasas@chromium.org</owner>
   <owner>guidou@chromium.org</owner>
   <owner>armax@chromium.org</owner>
@@ -5771,7 +5771,7 @@
 </histogram>
 
 <histogram name="Media.VideoCapture.ScaleOverride" units="units"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jophba@chromium.org</owner>
   <owner>klausw@chromium.org</owner>
   <summary>
@@ -5783,7 +5783,7 @@
 </histogram>
 
 <histogram name="Media.VideoCapture.ScaleOverrideChangeCount" units="units"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jophba@chromium.org</owner>
   <owner>klausw@chromium.org</owner>
   <summary>
@@ -5860,7 +5860,7 @@
 </histogram>
 
 <histogram name="Media.VideoCapture.Width" units="pixels"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>mcasas@chromium.org</owner>
   <owner>handellm@chromium.org</owner>
   <owner>jophba@chromium.org</owner>
@@ -6375,7 +6375,7 @@
 </histogram>
 
 <histogram name="Media.VTVDA.SessionFailureReason"
-    enum="VTVDASessionFailureType" expires_after="2024-03-03">
+    enum="VTVDASessionFailureType" expires_after="2024-05-05">
   <owner>sandersd@chromium.org</owner>
   <owner>media-dev-uma@chromium.org</owner>
   <summary>
@@ -7053,7 +7053,7 @@
 </histogram>
 
 <histogram name="MediaRouter.PresentationRequest.UrlBySink"
-    enum="PresentationUrlBySink" expires_after="2024-03-03">
+    enum="PresentationUrlBySink" expires_after="2024-05-05">
   <owner>mfoltz@chromium.org</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>
@@ -7189,7 +7189,7 @@
 </histogram>
 
 <histogram name="MediaRouter.Sink.SelectedType" enum="MediaSinkType"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>takumif@chromium.org</owner>
   <owner>openscreen-eng@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/memory/histograms.xml b/tools/metrics/histograms/metadata/memory/histograms.xml
index 56f075c7..21f7eb4 100644
--- a/tools/metrics/histograms/metadata/memory/histograms.xml
+++ b/tools/metrics/histograms/metadata/memory/histograms.xml
@@ -278,7 +278,7 @@
 </histogram>
 
 <histogram name="Memory.Browser.MemoryFootprint.Inactive" units="MB"
-    expires_after="2024-02-05">
+    expires_after="2024-05-05">
   <owner>justincohen@chromium.org</owner>
   <owner>ajuma@chromium.org</owner>
   <summary>
@@ -1026,7 +1026,7 @@
 
 <histogram
     name="Memory.Experimental.UserLevelMemoryPressureSignal.TotalPrivateMemoryFootprintAfter"
-    units="MB" expires_after="2024-03-03">
+    units="MB" expires_after="2024-05-05">
   <owner>tasak@google.com</owner>
   <owner>chrome-memory-tok@google.com</owner>
   <summary>
@@ -1037,7 +1037,7 @@
 
 <histogram
     name="Memory.Experimental.UserLevelMemoryPressureSignal.TotalPrivateMemoryFootprintBefore"
-    units="MB" expires_after="2024-03-03">
+    units="MB" expires_after="2024-05-05">
   <owner>tasak@google.com</owner>
   <owner>chrome-memory-tok@google.com</owner>
   <summary>
@@ -1055,7 +1055,7 @@
 
 <histogram
     name="Memory.Experimental.UserLevelMemoryPressureSignal.TotalPrivateMemoryFootprintVisibleOrHigherPriorityRenderersAfter"
-    units="MB" expires_after="2024-03-03">
+    units="MB" expires_after="2024-05-05">
   <owner>tasak@google.com</owner>
   <owner>chrome-memory-tok@google.com</owner>
   <summary>
@@ -1067,7 +1067,7 @@
 
 <histogram
     name="Memory.Experimental.UserLevelMemoryPressureSignal.TotalPrivateMemoryFootprintVisibleOrHigherPriorityRenderersBefore"
-    units="MB" expires_after="2024-03-03">
+    units="MB" expires_after="2024-05-05">
   <owner>tasak@google.com</owner>
   <owner>chrome-memory-tok@google.com</owner>
   <summary>
@@ -2293,7 +2293,7 @@
 </histogram>
 
 <histogram name="Memory.Total.RendererBlinkGC" units="MB"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>fdoray@chromium.org</owner>
   <owner>lizeb@chromium.org</owner>
   <summary>
@@ -2305,7 +2305,7 @@
 </histogram>
 
 <histogram name="Memory.Total.RendererBlinkGC.Fragmentation" units="MB"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>fdoray@chromium.org</owner>
   <owner>lizeb@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/mobile/histograms.xml b/tools/metrics/histograms/metadata/mobile/histograms.xml
index b1955e1..38d6993 100644
--- a/tools/metrics/histograms/metadata/mobile/histograms.xml
+++ b/tools/metrics/histograms/metadata/mobile/histograms.xml
@@ -601,7 +601,7 @@
 </histogram>
 
 <histogram name="Mobile.SystemNotification.Permission.Change"
-    enum="BooleanEnabled" expires_after="2024-03-03">
+    enum="BooleanEnabled" expires_after="2024-05-05">
   <owner>salg@google.com</owner>
   <owner>shaktisahu@chromium.org</owner>
   <summary>
@@ -612,7 +612,7 @@
 </histogram>
 
 <histogram name="Mobile.SystemNotification.Permission.OSPromptResult"
-    enum="BooleanEnabled" expires_after="2024-03-03">
+    enum="BooleanEnabled" expires_after="2024-05-05">
   <owner>salg@google.com</owner>
   <owner>shaktisahu@chromium.org</owner>
   <summary>
@@ -622,7 +622,7 @@
 </histogram>
 
 <histogram name="Mobile.SystemNotification.Permission.RationaleResult"
-    enum="NotificationRationaleResult" expires_after="2024-03-03">
+    enum="NotificationRationaleResult" expires_after="2024-05-05">
   <owner>salg@google.com</owner>
   <owner>shaktisahu@chromium.org</owner>
   <summary>
@@ -632,7 +632,7 @@
 </histogram>
 
 <histogram name="Mobile.SystemNotification.Permission.StartupRequestCount"
-    units="attempts" expires_after="2024-03-03">
+    units="attempts" expires_after="2024-05-05">
   <owner>salg@google.com</owner>
   <owner>shaktisahu@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/navigation/histograms.xml b/tools/metrics/histograms/metadata/navigation/histograms.xml
index 3a15ecd..e41ce5b 100644
--- a/tools/metrics/histograms/metadata/navigation/histograms.xml
+++ b/tools/metrics/histograms/metadata/navigation/histograms.xml
@@ -73,7 +73,7 @@
 </histogram>
 
 <histogram name="BackForwardCache.AllSites.HistoryNavigationOutcome"
-    enum="BackForwardCacheHistoryNavigationOutcome" expires_after="2024-03-03">
+    enum="BackForwardCacheHistoryNavigationOutcome" expires_after="2024-05-05">
   <owner>fergal@chromium.org</owner>
   <owner>bfcache-dev@chromium.org</owner>
   <summary>
@@ -104,7 +104,7 @@
 <histogram
     name="BackForwardCache.AllSites.HistoryNavigationOutcome.BrowsingInstanceNotSwappedReason"
     enum="BackForwardCacheBrowsingInstanceNotSwappedReason"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>fergal@chromium.org</owner>
   <owner>bfcache-dev@chromium.org</owner>
   <summary>
@@ -141,7 +141,7 @@
 
 <histogram
     name="BackForwardCache.AllSites.HistoryNavigationOutcome.NotRestoredReason"
-    enum="BackForwardCacheNotRestoredReason" expires_after="2024-03-03">
+    enum="BackForwardCacheNotRestoredReason" expires_after="2024-05-05">
   <owner>fergal@chromium.org</owner>
   <owner>bfcache-dev@chromium.org</owner>
   <summary>
@@ -157,7 +157,7 @@
 
 <histogram name="BackForwardCache.EvictedAfterDocumentRestoredReason"
     enum="BackForwardCacheEvictedAfterDocumentRestoredReason"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>fergal@chromium.org</owner>
   <owner>bfcache-dev@chromium.org</owner>
   <summary>
@@ -173,7 +173,7 @@
 </histogram>
 
 <histogram name="BackForwardCache.Eviction.Renderer"
-    enum="BackForwardCacheRendererEvictionReason" expires_after="2024-03-03">
+    enum="BackForwardCacheRendererEvictionReason" expires_after="2024-05-05">
   <owner>rakina@chromium.org</owner>
   <owner>bfcache-dev@chromium.org</owner>
   <summary>
@@ -194,7 +194,7 @@
 
 <histogram
     name="BackForwardCache.Experimental.UnexpectedIPCMessagePostedToCachedFrame.MethodHash"
-    enum="MojoInterfaceName" expires_after="2024-03-03">
+    enum="MojoInterfaceName" expires_after="2024-05-05">
   <owner>fergal@chromium.org</owner>
   <owner>bfcache-dev@chromium.org</owner>
   <summary>
@@ -225,7 +225,7 @@
 </histogram>
 
 <histogram name="BackForwardCache.HistoryNavigationOutcome"
-    enum="BackForwardCacheHistoryNavigationOutcome" expires_after="2024-03-03">
+    enum="BackForwardCacheHistoryNavigationOutcome" expires_after="2024-05-05">
   <owner>fergal@chromium.org</owner>
   <owner>bfcache-dev@chromium.org</owner>
   <summary>
@@ -239,7 +239,7 @@
 </histogram>
 
 <histogram name="BackForwardCache.HistoryNavigationOutcome.BlocklistedFeature"
-    enum="WebSchedulerTrackedFeature" expires_after="2024-03-03">
+    enum="WebSchedulerTrackedFeature" expires_after="2024-05-05">
   <owner>fergal@chromium.org</owner>
   <owner>bfcache-dev@chromium.org</owner>
   <summary>
@@ -257,7 +257,7 @@
 <histogram
     name="BackForwardCache.HistoryNavigationOutcome.BrowsingInstanceNotSwappedReason"
     enum="BackForwardCacheBrowsingInstanceNotSwappedReason"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>fergal@chromium.org</owner>
   <owner>bfcache-dev@chromium.org</owner>
   <summary>
@@ -275,7 +275,7 @@
 <histogram
     name="BackForwardCache.HistoryNavigationOutcome.DisabledForRenderFrameHostReason2"
     enum="BackForwardCacheDisabledForRenderFrameHostReason2"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>fergal@chromium.org</owner>
   <owner>bfcache-dev@chromium.org</owner>
   <summary>
@@ -332,7 +332,7 @@
 </histogram>
 
 <histogram name="BackForwardCache.HistoryNavigationOutcome.NotRestoredReason"
-    enum="BackForwardCacheNotRestoredReason" expires_after="2024-03-03">
+    enum="BackForwardCacheNotRestoredReason" expires_after="2024-05-05">
   <owner>fergal@chromium.org</owner>
   <owner>bfcache-dev@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/net/enums.xml b/tools/metrics/histograms/metadata/net/enums.xml
new file mode 100644
index 0000000..a7221822
--- /dev/null
+++ b/tools/metrics/histograms/metadata/net/enums.xml
@@ -0,0 +1,2935 @@
+<!--
+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.
+-->
+
+<!--
+
+This file describes the enumerations referenced by entries in histograms.xml for
+this directory. Some enums may instead be listed in the central enums.xml file
+at src/tools/metrics/histograms/enums.xml when multiple files use them.
+
+For best practices on writing enumerations descriptions, see
+https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md#Enum-Histograms
+
+Please follow the instructions in the OWNERS file in this directory to find a
+reviewer. If no OWNERS file exists, please consider signing up at
+go/reviewing-metrics (Googlers only), as all subdirectories are expected to
+have an OWNERS file. As a last resort you can send the CL to
+chromium-metrics-reviews@google.com.
+-->
+
+<histogram-configuration>
+
+<!-- Enum types -->
+
+<enums>
+
+<enum name="AcceptChEntries">
+  <int value="0" label="no entries"/>
+  <int value="1" label="only valid entries"/>
+  <int value="2" label="only invalid entries"/>
+  <int value="3" label="both valid and invalid entries"/>
+</enum>
+
+<enum name="AddressFamily">
+  <int value="0" label="Unspecified"/>
+  <int value="1" label="IPv4"/>
+  <int value="2" label="IPv6"/>
+</enum>
+
+<enum name="AlpsDecoderError">
+  <int value="0" label="NoError"/>
+  <int value="1" label="FramingError"/>
+  <int value="2" label="ForbiddenFrame"/>
+  <int value="3" label="NotOnFrameBoundary"/>
+  <int value="4" label="SettingsWithAck"/>
+  <int value="5" label="AcceptChInvalidStream"/>
+  <int value="6" label="AcceptChWithFlags"/>
+  <int value="7" label="AcceptChMalformed"/>
+</enum>
+
+<enum name="AlternateProtocolUsage">
+  <int value="0" label="ALTERNATE_PROTOCOL_USAGE_NO_RACE"/>
+  <int value="1" label="ALTERNATE_PROTOCOL_USAGE_WON_RACE"/>
+  <int value="2" label="ALTERNATE_PROTOCOL_USAGE_MAIN_JOB_WON_RACE"/>
+  <int value="3" label="ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING"/>
+  <int value="4" label="ALTERNATE_PROTOCOL_USAGE_BROKEN"/>
+  <int value="5"
+      label="ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_WITHOUT_RACE"/>
+  <int value="6" label="ALTERNATE_PROTOCOL_USAGE_DNS_ALPN_H3_JOB_WON_RACE"/>
+  <int value="7" label="ALTERNATE_PROTOCOL_USAGE_UNSPECIFIED_REASON"/>
+</enum>
+
+<enum name="AlternativeServiceType">
+  <int value="0" label="No alternative service"/>
+  <int value="1" label="QUIC, destination same as origin"/>
+  <int value="2" label="QUIC, destination different from origin"/>
+  <int value="3" label="Not QUIC, destination same as origin"/>
+  <int value="4" label="Not QUIC, destination different from origin"/>
+</enum>
+
+<enum name="BodyConsumerBaseFetchCheckPoint">
+  <int value="0" label="BodyConsumerBase Constructor"/>
+  <int value="1" label="BodyConsumerBase::DidFetchDataLoadFailed"/>
+</enum>
+
+<enum name="BooleanBroken">
+  <int value="0" label="Not Broken"/>
+  <int value="1" label="Broken"/>
+</enum>
+
+<enum name="BooleanCoalesced">
+  <int value="0" label="not coalesced"/>
+  <int value="1" label="coalesced"/>
+</enum>
+
+<enum name="BooleanConfirmed">
+  <int value="0" label="Not Confirmed"/>
+  <int value="1" label="Confirmed"/>
+</enum>
+
+<enum name="BooleanExceeded">
+  <int value="0" label="Not exceeded"/>
+  <int value="1" label="Exceeded"/>
+</enum>
+
+<enum name="BooleanOutOfDate">
+  <int value="0" label="Up-to-date"/>
+  <int value="1" label="Out-of-date"/>
+</enum>
+
+<enum name="BooleanPathIsInformative">
+  <int value="0" label="Path contains nothing except possibly a slash"/>
+  <int value="1" label="Path contains text beyond just an opening slash"/>
+</enum>
+
+<enum name="BooleanPreferred">
+  <int value="0" label="Not Preferred"/>
+  <int value="1" label="Preferred"/>
+</enum>
+
+<enum name="BooleanTooMany">
+  <int value="0" label="Correct"/>
+  <int value="1" label="Too many"/>
+</enum>
+
+<enum name="BrokenAlternateProtocolLocation">
+  <int value="0" label="HTTP_STREAM_FACTORY_JOB"/>
+  <int value="1" label="QUIC_STREAM_FACTORY"/>
+  <int value="2" label="HTTP_STREAM_FACTORY_JOB_ALT"/>
+  <int value="3" label="HTTP_STREAM_FACTORY_JOB_MAIN"/>
+  <int value="4" label="QUIC_HTTP_STREAM"/>
+  <int value="5" label="HTTP_NETWORK_TRANSACTION"/>
+</enum>
+
+<enum name="CertificateChangeNotificationType">
+  <int value="0" label="Trust"/>
+  <int value="1" label="Client Cert"/>
+</enum>
+
+<enum name="ConnectionInfo">
+  <summary>
+    Application protocol used for HTTP response as defined in
+    net::HttpResponseInfo::ConnectionInfo.
+  </summary>
+  <int value="0" label="unknown"/>
+  <int value="1" label="HTTP/1.1"/>
+  <int value="2" label="SPDY/2 (deprecated)"/>
+  <int value="3" label="SPDY/3 (deprecated)"/>
+  <int value="4" label="HTTP/2"/>
+  <int value="5" label="QUIC (unknown version)"/>
+  <int value="6" label="HTTP/2 draft-14 (deprecated)"/>
+  <int value="7" label="HTTP/2 draft-15 (deprecated)"/>
+  <int value="8" label="HTTP/0.9"/>
+  <int value="9" label="HTTP/1.0"/>
+  <int value="10" label="QUIC/32"/>
+  <int value="11" label="QUIC/33"/>
+  <int value="12" label="QUIC/34"/>
+  <int value="13" label="QUIC/35"/>
+  <int value="14" label="QUIC/36"/>
+  <int value="15" label="QUIC/37"/>
+  <int value="16" label="QUIC/38"/>
+  <int value="17" label="QUIC/39"/>
+  <int value="18" label="QUIC/40"/>
+  <int value="19" label="QUIC/41"/>
+  <int value="20" label="QUIC/42"/>
+  <int value="21" label="QUIC/43"/>
+  <int value="22" label="HTTP/3 (Q099)"/>
+  <int value="23" label="QUIC/44"/>
+  <int value="24" label="QUIC/45"/>
+  <int value="25" label="QUIC/46"/>
+  <int value="26" label="QUIC/47"/>
+  <int value="27" label="QUIC/999"/>
+  <int value="28" label="HTTP/3 (Q048)"/>
+  <int value="29" label="HTTP/3 (Q049)"/>
+  <int value="30" label="HTTP/3 (Q050)"/>
+  <int value="31" label="HTTP/3 (T048)"/>
+  <int value="32" label="HTTP/3 (T049)"/>
+  <int value="33" label="HTTP/3 (T050)"/>
+  <int value="34" label="HTTP/3 (T099)"/>
+  <int value="35" label="HTTP/3 (draft-25)"/>
+  <int value="36" label="HTTP/3 (draft-27)"/>
+  <int value="37" label="HTTP/3 (draft-28)"/>
+  <int value="38" label="HTTP/3 (draft-29)"/>
+  <int value="39" label="HTTP/3 (T051)"/>
+  <int value="40" label="QUIC (RFC)"/>
+  <int value="41" label="QUICv2 draft-01 (deprecated)"/>
+  <int value="42" label="QUICv2 draft-08"/>
+</enum>
+
+<enum name="ContentEncodingType">
+  <int value="0" label="Unknown"/>
+  <int value="1" label="Brotli"/>
+  <int value="2" label="GZip"/>
+  <int value="3" label="Deflate"/>
+  <int value="4" label="Zstd"/>
+</enum>
+
+<enum name="CorsAccessCheckError">
+  <summary>
+    The detailed error type for CORS check failures. See
+    services/network/public/mojom/cors.mojom for detailed information.
+  </summary>
+  <int value="0" label="kDisallowedByMode"/>
+  <int value="1" label="kInvalidResponse"/>
+  <int value="2" label="kWildcardOriginNotAllowed"/>
+  <int value="3" label="kMissingAllowOriginHeader"/>
+  <int value="4" label="kMultipleAllowOriginValues"/>
+  <int value="5" label="kInvalidAllowOriginValue"/>
+  <int value="6" label="kAllowOriginMismatch"/>
+  <int value="7" label="kInvalidAllowCredentials"/>
+  <int value="8" label="kCorsDisabledScheme"/>
+  <int value="9" label="kPreflightInvalidStatus"/>
+  <int value="10" label="kPreflightDisallowedRedirect"/>
+  <int value="11" label="kPreflightWildcardOriginNotAllowed"/>
+  <int value="12" label="kPreflightMissingAllowOriginHeader"/>
+  <int value="13" label="kPreflightMultipleAllowOriginValues"/>
+  <int value="14" label="kPreflightInvalidAllowOriginValue"/>
+  <int value="15" label="kPreflightAllowOriginMismatch"/>
+  <int value="16" label="kPreflightInvalidAllowCredentials"/>
+  <int value="17" label="kPreflightMissingAllowPrivateNetwork"/>
+  <int value="18" label="kPreflightInvalidAllowPrivateNetwork"/>
+  <int value="19" label="kInvalidAllowMethodsPreflightResponse"/>
+  <int value="20" label="kInvalidAllowHeadersPreflightResponse"/>
+  <int value="21" label="kMethodDisallowedByPreflightResponse"/>
+  <int value="22" label="kHeaderDisallowedByPreflightResponse"/>
+  <int value="23" label="kRedirectContainsCredentials"/>
+  <int value="24" label="kInsecurePrivateNetwork"/>
+  <int value="25" label="kInvalidPrivateNetworkAccess"/>
+  <int value="26" label="kUnexpectedPrivateNetworkAccess"/>
+  <int value="27" label="kPreflightMissingPrivateNetworkAccessId"/>
+  <int value="28" label="kPreflightMissingPrivateNetworkAccessName"/>
+  <int value="29" label="kPrivateNetworkAccessPermissionUnavailable"/>
+  <int value="30" label="kPrivateNetworkAccessPermissionDenied"/>
+</enum>
+
+<enum name="DNS.AttemptType">
+  <int value="0" label="DnsUDPAttempt"/>
+  <int value="1" label="DnsTCPAttempt due to low UDP entropy"/>
+  <int value="2" label="DnsTCPAttempt due to retry due to UDP trucation"/>
+  <int value="3" label="DnsHTTPAttempt"/>
+</enum>
+
+<enum name="DNS.SvcbHttpsTransactionError">
+  <int value="0" label="No transaction error"/>
+  <int value="1" label="Insecure DNS transaction error (never task-fatal)"/>
+  <int value="2" label="Non-task-fatal Secure DNS transaction error"/>
+  <int value="3"
+      label="Would be task-fatal transaction error but finch param disabled"/>
+  <int value="4" label="Task-fatal transaction error"/>
+</enum>
+
+<enum name="DNS.TaskTypeMetadataAvailability">
+  <int value="0" label="SYSTEM, no metadata"/>
+  <int value="1" label="SYSTEM, with metadata"/>
+  <int value="2" label="DNS, no metadata"/>
+  <int value="3" label="DNS, with metadata"/>
+  <int value="4" label="SECURE_DNS, no metadata"/>
+  <int value="5" label="SECURE_DNS, with metadata"/>
+  <int value="6" label="MDNS, no metadata"/>
+  <int value="7" label="MDNS, with metadata"/>
+  <int value="8" label="CACHE_LOOKUP, no metadata"/>
+  <int value="9" label="CACHE_LOOKUP, with metadata"/>
+  <int value="10" label="INSECURE_CACHE_LOOKUP, no metadata"/>
+  <int value="11" label="INSECURE_CACHE_LOOKUP, with metadata"/>
+  <int value="12" label="SECURE_CACHE_LOOKUP, no metadata"/>
+  <int value="13" label="SECURE_CACHE_LOOKUP, with metadata"/>
+  <int value="14" label="CONFIG_PRESET, no metadata"/>
+  <int value="15" label="CONFIG_PRESET, with metadata"/>
+  <int value="16" label="NAT64, no metadata"/>
+  <int value="17" label="NAT64, with metadata"/>
+  <int value="18" label="HOSTS, no metadata"/>
+  <int value="19" label="HOSTS, with metadata"/>
+</enum>
+
+<enum name="DNS.UdpLowEntropyReason">
+  <int value="0" label="Multiple recent reassignments of the same UDP port"/>
+  <int value="1"
+      label="DNS query/response ID mismatches, where response ID is
+             recognized from a recent query"/>
+  <int value="2"
+      label="DNS query/response ID mismatches, where response ID is
+             unrecognized"/>
+  <int value="3" label="Exhaustion of process-wide UDP socket limit"/>
+</enum>
+
+<enum name="DNS.WindowsCompatibility">
+  <int value="0" label="Compatible"/>
+  <int value="1" label="Incompatible resolution policy"/>
+  <int value="2" label="Incompatible proxy"/>
+  <int value="3" label="Incompatible resolution policy and proxy"/>
+  <int value="4" label="Incompatible VPN"/>
+  <int value="5" label="Incompatible resolution policy and VPN"/>
+  <int value="6" label="Incompatible proxy and VPN"/>
+  <int value="7" label="Incompatible resolution policy, proxy and VPN"/>
+  <int value="8" label="Incompatible adapter specific nameserver"/>
+  <int value="9"
+      label="Incompatible resolution policy and adapter specific nameserver"/>
+  <int value="10" label="Incompatible proxy and adapter specific nameserver"/>
+  <int value="11"
+      label="Incompatible resolution policy, proxy and adapter specific
+             nameserver"/>
+  <int value="12" label="Incompatible VPN and adapter specific nameserver"/>
+  <int value="13"
+      label="Incompatible resolution policy, VPN and adapter specific
+             nameserver"/>
+  <int value="14"
+      label="Incompatible proxy, VPN and adapter specific nameserver"/>
+  <int value="15"
+      label="Incompatible resolution policy, proxy, VPN and adapter specific
+             nameserver"/>
+</enum>
+
+<enum name="DohServerAutoupgradeStatus">
+  <int value="0" label="SuccessWithNoPriorFailures"/>
+  <int value="1" label="SuccessWithSomePriorFailures"/>
+  <int value="2" label="FailureWithSomePriorSuccesses"/>
+  <int value="3" label="FailureWithNoPriorSuccesses"/>
+</enum>
+
+<enum name="DomainReliabilityBeaconOutcome">
+  <int value="0" label="Unknown (should not be recorded)"/>
+  <int value="1" label="Uploaded successfully"/>
+  <int value="2" label="Expired"/>
+  <int value="3" label="Evicted"/>
+  <int value="4" label="Browsing data cleared"/>
+  <int value="5" label="Deleted at shutdown"/>
+</enum>
+
+<enum name="ECDHECurves">
+  <int value="21" label="P-224"/>
+  <int value="23" label="P-256"/>
+  <int value="24" label="P-384"/>
+  <int value="25" label="P-521"/>
+  <int value="29" label="X25519"/>
+  <int value="16696" label="CECPQ2"/>
+  <int value="25497" label="Kyber+X25519"/>
+</enum>
+
+<enum name="FetchManagerLoaderCheckPoint">
+  <int value="0" label="FetchManager::Loader Constructor"/>
+  <int value="1" label="FetchManager::Loader::Failed"/>
+</enum>
+
+<enum name="Http2WireErrorCodes">
+  <summary>
+    Error codes defined at
+    https://www.iana.org/assignments/http2-parameters/http2-parameters.xhtml#error-code
+  </summary>
+  <int value="0" label="NO_ERROR"/>
+  <int value="1" label="PROTOCOL_ERROR"/>
+  <int value="2" label="INTERNAL_ERROR"/>
+  <int value="3" label="FLOW_CONTROL_ERROR"/>
+  <int value="4" label="SETTINGS_TIMEOUT"/>
+  <int value="5" label="STREAM_CLOSED"/>
+  <int value="6" label="FRAME_SIZE_ERROR"/>
+  <int value="7" label="REFUSED_STREAM"/>
+  <int value="8" label="CANCEL"/>
+  <int value="9" label="COMPRESSION_ERROR"/>
+  <int value="10" label="CONNECT_ERROR"/>
+  <int value="11" label="ENHANCE_YOUR_CALM"/>
+  <int value="12" label="INADEQUATE_SECURITY"/>
+  <int value="13" label="HTTP_1_1_REQUIRED"/>
+</enum>
+
+<enum name="HttpAuthCount">
+  <int value="0" label="Basic Start"/>
+  <int value="1" label="Basic Reject"/>
+  <int value="2" label="Digest Start"/>
+  <int value="3" label="Digest Reject"/>
+  <int value="4" label="NTLM Start"/>
+  <int value="5" label="NTLM Reject"/>
+  <int value="6" label="Negotiate Start"/>
+  <int value="7" label="Negotiate Reject"/>
+  <int value="8" label="SpdyProxy Start (Deprecated)"/>
+  <int value="9" label="SpdyProxy Reject (Deprecated)"/>
+</enum>
+
+<enum name="HttpAuthNtlmV2Usage">
+  <int value="0" label="Disabled over unsecured connection"/>
+  <int value="1" label="Disabled over secure connection"/>
+  <int value="2" label="Enabled over unsecured connection"/>
+  <int value="3" label="Enabled over secure connection"/>
+</enum>
+
+<enum name="HttpAuthPromptType">
+  <int value="0" label="Main frame with interstitial">
+    Auth prompt displayed over a blank interstitial
+  </int>
+  <int value="1" label="Main frame without interstitial">
+    Auth prompt displayed for the main frame, without a blank interstitial
+  </int>
+  <int value="2" label="Same origin subresource">
+    Auth prompt displayed for a subresource from the same origin
+  </int>
+  <int value="3" label="Cross origin subresource">
+    Auth prompt displayed for a subresource from a different origin
+  </int>
+</enum>
+
+<enum name="HttpAuthTarget">
+  <int value="0" label="Basic Proxy"/>
+  <int value="1" label="Basic Secure Proxy"/>
+  <int value="2" label="Basic Server"/>
+  <int value="3" label="Basic Secure Server"/>
+  <int value="4" label="Digest Proxy"/>
+  <int value="5" label="Digest Secure Proxy"/>
+  <int value="6" label="Digest Server"/>
+  <int value="7" label="Digest Secure Server"/>
+  <int value="8" label="NTLM Proxy"/>
+  <int value="9" label="NTLM Secure Proxy"/>
+  <int value="10" label="NTLM Server"/>
+  <int value="11" label="NTLM Secure Server"/>
+  <int value="12" label="Negotiate Proxy"/>
+  <int value="13" label="Negotiate Secure Proxy"/>
+  <int value="14" label="Negotiate Server"/>
+  <int value="15" label="Negotiate Secure Server"/>
+  <int value="16" label="SpdyProxy (Deprecated)"/>
+  <int value="17" label="SpdyProxy Secure (Deprecated)"/>
+  <int value="18" label="SpdyProxy Server (Invalid)"/>
+  <int value="19" label="SpdyProxy Secure Server (Invalid)"/>
+</enum>
+
+<enum name="HttpCachePattern">
+  <int value="0" label="Undefined"/>
+  <int value="1" label="Not Covered"/>
+  <int value="2" label="Not Cached"/>
+  <int value="3" label="Used"/>
+  <int value="4" label="Validated"/>
+  <int value="5" label="Updated"/>
+  <int value="6" label="CantConditionalize"/>
+</enum>
+
+<enum name="HttpNetworkTransactionRetryReason">
+  <int value="0" label="HttpRequestTimeout"/>
+  <int value="1" label="HttpMisdirectedRequest"/>
+  <int value="2" label="Http11Required"/>
+  <int value="3" label="SslClientAuthSignatureFailed"/>
+  <int value="4" label="ConnectionReset"/>
+  <int value="5" label="ConnectionClosed"/>
+  <int value="6" label="ConnectionAborted"/>
+  <int value="7" label="SocketNotConnected"/>
+  <int value="8" label="EmptyResponse"/>
+  <int value="9" label="EarlyDataRejected"/>
+  <int value="10" label="WrongVersionOnEarlyData"/>
+  <int value="11" label="Http2PingFailed"/>
+  <int value="12" label="Http2ServerRefusedStream"/>
+  <int value="13" label="Http2PushedStreamNotAvailable"/>
+  <int value="14" label="Http2ClaimedPushedStreamResetByServer"/>
+  <int value="15" label="Http2PushedResponseDoesNotMatch"/>
+  <int value="16" label="QuicHandshakeFailed"/>
+  <int value="17" label="QuicGoawayRequestCanBeRetried"/>
+  <int value="18" label="QuicProtocolError"/>
+</enum>
+
+<enum name="HttpssvcDnsRcode">
+  <summary>
+    Tracks the result of querying for an INTEGRITY or HTTPSSVC record. This enum
+    can represent each of Chrome's supported RCODE values as well as any
+    unrecognized RCODE values. It also has the TimedOut value to represent
+    queries that timed out.
+
+    IANA registry:
+    https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml
+  </summary>
+  <int value="0" label="TimedOut"/>
+  <int value="1" label="UnrecognizedRcode"/>
+  <int value="2" label="MissingDnsResponse (network error)"/>
+  <int value="3" label="NOERROR"/>
+  <int value="4" label="FORMERR"/>
+  <int value="5" label="SERVFAIL"/>
+  <int value="6" label="NXDOMAIN"/>
+  <int value="7" label="NOTIMP"/>
+  <int value="8" label="REFUSED"/>
+</enum>
+
+<enum name="InitialRttEstimateSource">
+  <int value="0" label="Default"/>
+  <int value="1" label="Cached"/>
+  <int value="2" label="2G"/>
+  <int value="3" label="3G"/>
+</enum>
+
+<enum name="JobProtocolErrorLocation">
+  <int value="0" label="kSessionStartReadingFailedAsync"/>
+  <int value="1" label="kSessionStartReadingFailedSync"/>
+  <int value="2" label="kCreateSessionFailedAsync"/>
+  <int value="3" label="kCreateSessionFailedSync"/>
+  <int value="4" label="CryptoConnectFailedSync"/>
+  <int value="5" label="CryptoConnectFailedAsync"/>
+</enum>
+
+<enum name="MediaResponseCacheType">
+  <int value="0" label="Transaction Cache Enabled"/>
+  <int value="1" label="Transaction Cache Disabled"/>
+</enum>
+
+<enum name="MultiPortStatusOnMigration">
+  <int value="0" label="Not validated"/>
+  <int value="1" label="Pending refresh validation"/>
+  <int value="2" label="Waiting for refresh validation"/>
+</enum>
+
+<enum name="NegotiatedHttpDatagramVersion">
+  <int value="0" label="Not supported"/>
+  <int value="1" label="draft-04"/>
+  <int value="2" label="rfc"/>
+</enum>
+
+<enum name="NegotiatedWebTransportVersion">
+  <int value="0" label="draft-02"/>
+  <int value="1" label="draft-07"/>
+</enum>
+
+<enum name="NetCertificateNameNormalization">
+  <int value="0" label="Error parsing certificate chain"/>
+  <int value="1" label="Byte equal Names"/>
+  <int value="2" label="Normalized Names"/>
+  <int value="3" label="Chain contained only one certificate"/>
+</enum>
+
+<enum name="NetErrorOfflineSuggestionType">
+  <int value="0" label="Prefetched Page">
+    A Prefetched article that has been offlined.
+  </int>
+  <int value="1" label="Video">
+    A video file previously downloaded by the user.
+  </int>
+  <int value="2" label="Audio">
+    An audio file previously downloaded by the user.
+  </int>
+  <int value="3" label="Other Page">
+    An offline page previously downloaded by the user.
+  </int>
+</enum>
+
+<enum name="NetErrorPageEvents">
+  <int value="0" label="Error Page Shown">
+    An error page was shown. This bucket encompasses all others and works as a
+    total count for error pages (instead of the histogram's total sample count
+    which doesn't reflect that information).
+  </int>
+  <int value="1" label="Reload Button Shown">
+    An error page was shown with at least a &quot;Reload&quot; button on it.
+  </int>
+  <int value="2" label="Reload Button Clicked">
+    An error page was shown with at least a &quot;Reload&quot; button on it and
+    the user pressed that button.
+  </int>
+  <int value="3" label="Reload Button Click Load Error">
+    An error page was previously loaded with a &quot;Reload&quot; button and
+    another load error happened as a result of the user pressing that button.
+  </int>
+  <int value="4" label="Show Saved Copy Button Shown">
+    An error page was shown with at least a &quot;Show Saved Copy&quot; button
+    on it.
+  </int>
+  <int value="5" label="Show Saved Copy Button Clicked">
+    An error page was shown with at least a &quot;Show Saved Copy&quot; button
+    on it and the user pressed that button.
+  </int>
+  <int value="6" label="Show Saved Copy Button Click Load Error">
+    An error page was previously loaded with a &quot;Show Saved Copy&quot;
+    button and another load error happened as a result of the user pressing that
+    button.
+  </int>
+  <int value="7" label="More Button Clicked">
+    An error page was shown with at least a &quot;More&quot; (aka
+    &quot;Details&quot;) button on it and the user pressed that button.
+  </int>
+  <int value="8" label="Browser Initiated Reload">
+    An error page was previously loaded and the user started a reload by
+    pressing the browser's reload button.
+  </int>
+  <int value="9" label="Both Reload And Show Saved Copy Buttons Shown">
+    An error page was shown with at least a &quot;Reload&quot; and a &quot;Show
+    Saved Copy&quot; buttons on it. Note that this is not exclusive with the
+    respective individual button buckets.
+  </int>
+  <int value="10"
+      label="Both Reload And Show Saved Copy Buttons Shown, Reload Clicked">
+    An error page was shown with at least a &quot;Reload&quot; and a &quot;Show
+    Saved Copy&quot; buttons on it and the user pressed the &quot;Reload&quot;
+    button. Note that this is not exclusive with the respective individual
+    button buckets.
+  </int>
+  <int value="11"
+      label="Both Reload And Show Saved Copy Buttons Shown, Show Saved Copy
+             Clicked">
+    An error page was shown with at least a &quot;Reload&quot; and a &quot;Show
+    Saved Copy&quot; buttons on it and the user pressed the &quot;Show Saved
+    Copy&quot; button. Note that this is not exclusive with the respective
+    individual button buckets.
+  </int>
+  <int value="12" label="Easter egg activated">
+    An error page was shown with the offline dino image and and the user
+    activated it (to play the dino game).
+  </int>
+  <int value="13" label="Show Cached Copy button shown">
+    An error page was shown with at least a &quot;Show Cached Copy&quot; button
+    on it.
+  </int>
+  <int value="14" label="Show Cached Copy button clicked">
+    An error page was shown with at least a &quot;Show Cached Copy&quot; button
+    on it and the user pressed that button.
+  </int>
+  <int value="15" label="Show Cached Page button shown">Obsolete.</int>
+  <int value="16" label="Show Cached Page button clicked">Obsolete.</int>
+  <int value="17" label="Diagnose button clicked">
+    An error page was shown with at least a &quot;Diagnose Error&quot; button on
+    it and the user pressed that button.
+  </int>
+  <int value="18" label="Show Offline Pages Button Shown">Obsolete.</int>
+  <int value="19" label="Show Offline Pages Button Clicked">Obsolete.</int>
+  <int value="20" label="Show Offline Copy Button Shown">Obsolete.</int>
+  <int value="21" label="Show Offline Copy Button Clicked">Obsolete.</int>
+  <int value="22" label="Download Button Shown">
+    An error page was shown with at least a &quot;Download Page Later&quot;
+    button on it.
+  </int>
+  <int value="23" label="Download Button Clicked">
+    An error page was shown with at least a &quot;Download Page Later&quot;
+    button on it and the user pressed that button.
+  </int>
+  <int value="24" label="Offline Suggestions List Shown">
+    A list containing at least one item of offline content suggestions was shown
+    in the expanded/shown state.
+  </int>
+  <int value="25" label="Offline Suggestion List Item Clicked">
+    An item from the offline content suggestions list was clicked.
+  </int>
+  <int value="26" label="Downloads Page Button Clicked">
+    A link that opens the downloads page was clicked.
+  </int>
+  <int value="27" label="Offline Content Summary Shown">
+    A summary of available offline content was shown.
+  </int>
+  <int value="28" label="Offline Suggestions List Shown Collapsed">
+    A list containing at least one item of offline content suggestions was shown
+    in the collapsed/hidden state.
+  </int>
+  <int value="29" label="Offline error shown">
+    The error page was shown because the device is offline (dino page).
+  </int>
+  <int value="30" label="Sign in to network button clicked">
+    An error page was shown with at least a &quot;Sign in to network&quot;
+    button on it and the user pressed that button.
+  </int>
+</enum>
+
+<enum name="NetFilterType2">
+  <summary>
+    Specific content decoding filter. See net::SourceStream::SourceType for more
+    details
+  </summary>
+  <int value="0" label="Brotli"/>
+  <int value="1" label="Deflate"/>
+  <int value="2" label="GZIP"/>
+  <int value="3" label="GZIPFallback"/>
+  <int value="4" label="SDCH"/>
+  <int value="5" label="SDCHPossible"/>
+  <int value="6" label="Invalid"/>
+  <int value="7" label="None"/>
+  <int value="8" label="Rejected">
+    Unlike other values, this one is reported from HttpNetworkTransaction in a
+    case when an unadvertised, but known encoding appears in a
+    &quot;Content-Encoding&quot; header, and is thus not comparable with the
+    other values, which are potentially returned from cached entries.
+  </int>
+  <int value="9" label="Unknown">
+    Reported from URLRequestHttpJob::SetUpSourceStream when an unknown encoding
+    appears in a &quot;Content-Encoding&quot; header. Despite being reported in
+    this histogram, this does not cause a CONTENT_DECODING_FAILED error.
+  </int>
+</enum>
+
+<enum name="NetNetworkErrorLoggingRequestOutcome">
+  <int value="0" label="Discarded: no NetworkErrorLoggingService"/>
+  <int value="1" label="Discarded: no ReportingService"/>
+  <int value="2" label="Discarded: insecure origin"/>
+  <int value="3" label="Discarded: no origin policy"/>
+  <int value="4" label="Discarded: unmapped error"/>
+  <int value="5" label="Discarded: Reporting upload"/>
+  <int value="6" label="Discarded: unsampled success"/>
+  <int value="7" label="Discarded: unsampled failure"/>
+  <int value="8" label="Queued"/>
+  <int value="9" label="Discarded: include_subdomains without DNS error"/>
+  <int value="10" label="Discarded: IP address mismatch"/>
+</enum>
+
+<enum name="NetReportingHeaderType">
+  <int value="0" label="Report-To"/>
+  <int value="1" label="Invalid Report-To"/>
+  <int value="2" label="Reporting-Endpoints"/>
+  <int value="3" label="Invalid Reporting-Endpoints"/>
+</enum>
+
+<enum name="NetReportingUploadHeaderType">
+  <int value="0" label="ReportTo"/>
+  <int value="1" label="ReportingEndpoints"/>
+</enum>
+
+<enum name="NetTrustAnchors">
+<!-- Generated from net/data/ssl/root_stores/root_stores.json.
+Called by update_net_trust_anchors.py.-->
+
+  <int value="0" label="Unknown or locally-installed trust anchor"/>
+  <int value="1"
+      label="1d75d0831b9e0885394d32c7a1bfdb3dbc1c28e2b0e8391fb135981dbc5ba936"/>
+  <int value="2"
+      label="4691cbfde84a6b6052ddbe152bb0c216ae25a86e5747813dbc0f147f338570be"/>
+  <int value="3"
+      label="c73afc2eba770d0cbc1ee41f252b52e8a93d12b72dccec031d8d839cbf818a79"/>
+  <int value="4"
+      label="a99972ce1f6c581d0097f62618062e53157b5276e1ec6651a3157057f057b339"/>
+  <int value="5"
+      label="628e3a1156f6faa92f94b409258d4cba3f2047480d30194faf3fbed05eaeb5b2"/>
+  <int value="6"
+      label="2b071c59a0a0ae76b0eadb2bad23bad4580b69c3601b630c2eaf0613afa83f92"/>
+  <int value="7"
+      label="8a27b5557b4bec7cc0305fbf3d53d1f71cd3f34910c5d65e27ecddb82077ba3d"/>
+  <int value="8"
+      label="cbe5ac15d88b5cac3f81e6df3bfb57bea60958813a47b77f3c5cb6b98191bdb5"/>
+  <int value="9"
+      label="e2d891efb738669105d530de5ed72e2b2ac3f4a67078b5349b3fdaca496f5eb8"/>
+  <int value="10"
+      label="563b3caf8cfef34c2335caf560a7a95906e8488462eb75ac59784830df9e5b2b"/>
+  <int value="11"
+      label="9dd55fc573f546cb6a3831d1112d8710a6f4f82dc87f5fae9d3a1a028dd36e4b"/>
+  <int value="12"
+      label="772fccca7d1646d60628134ff2e6e7f5ba095898be59698bce9d15f96f69a9f3"/>
+  <int value="13"
+      label="3c35e164bedd2cf12beb83ecff78b5e80da8158d2830217e4ebffce8928899a6"/>
+  <int value="14"
+      label="3b45918205c591298a1922a58b4921d01f648fa9d28bdddfad24aeec5942cfbf"/>
+  <int value="15"
+      label="a81293445db196a2030f9e455fe3c74a9a4f8317b02b01406027a8708174434c"/>
+  <int value="16"
+      label="eca0f181402ce7a8652b31b4d036df247e3a30b7f41a50d91ec4f90b006b43a1"/>
+  <int value="17"
+      label="8d767764b3cbda08929d072a22a561f4dcdd1bc57d3cbddc948c47d2b47f9122"/>
+  <int value="18"
+      label="706bb1017c855c59169bad5c1781cf597f12d2cad2f63d1a4aa37493800ffb80"/>
+  <int value="19"
+      label="ced43902ab5fb57b442322dc0e172a4fb55f7178b808f94e780a6fd6cc6bd818"/>
+  <int value="20"
+      label="6bcfc86c8ddc2af2e6a1180a2ddabb37b7ea3755316b64b9b8951bf0ca351f06"/>
+  <int value="21"
+      label="5632d97bfa775bf3c99ddea52fc2553410864016729c52dd6524c8a9c3b4489f"/>
+  <int value="22"
+      label="15f14ac45c9c7da233d3479164e8137fe35ee0f38ae858183f08410ea82ac4b4"/>
+  <int value="23"
+      label="bcfb44aab9ad021015706b4121ea761c81c9e88967590f6f94ae744dc88b78fb"/>
+  <int value="24"
+      label="acf65e1d62cb58a2bafd6ffab40fb88699c47397cf5cb483d42d69cad34cd48b"/>
+  <int value="25"
+      label="b03d87b056d08cc9d4e675ef19ca83ab53532168a8258598be72e6d85c7dd7c1"/>
+  <int value="26"
+      label="c3bc6100f57e320d8659f22584677e56860aab1014e0084a496fff8c880b6ba3"/>
+  <int value="27"
+      label="32d180ed31c935589ec9dbbb722123b883b5fc2dc10f9fca3a95d77e1bfcb534"/>
+  <int value="28"
+      label="fcf7da983603e88862030d96137d8e13031badfb4d56c1fd4cacc339f6bdbb2a"/>
+  <int value="29"
+      label="e42f24bd4d37f4aa2e56b979d83d1e65219fe0e9e3a382a1b3cb66c93955de75"/>
+  <int value="30"
+      label="7e8782c150ce3952f802e636023a5d3e95bb5d68e33e85adb2ba178125cebf15"/>
+  <int value="31"
+      label="aff988906dde12955d9bebbf928fdcc31cce328d5b9384f21c8941ca26e20391"/>
+  <int value="32"
+      label="ce24eb0626defd8168c96a7701f09301600fe5dd0dbce58e9c97b830af02ef28"/>
+  <int value="33"
+      label="63d9af9b47b1064d49a10e7b7fd566dbc8caa399459bfc2829c571ad8c6ef34a"/>
+  <int value="34"
+      label="942a6916a6e4ae527711c5450247a2a74fb8e156a8254ca66e739a11493bb445"/>
+  <int value="35"
+      label="40fcfc28875dccbfebcbdf6cd7433312da63c4efcf3bd7b1b505c22020ae0274"/>
+  <int value="36"
+      label="05570ae6eb0fceb4210e6db79486b7094caf200401e149b6677441b5f25e449b"/>
+  <int value="37"
+      label="05e77ef1fdfe05e2dca522cae64d8379a041b7b4f16c7cae36067a7f72a14872"/>
+  <int value="38"
+      label="1ea3c5e43ed66c2da2983a42a4a79b1e906786ce9f1b58621419a00463a87d38"/>
+  <int value="39"
+      label="1a7a3a1a68dd2361e3f3bb855f3b26fcd88b197d8dd4de06cf1b362ac89ec13b"/>
+  <int value="40"
+      label="15e7e717b428feee3af3afd9150dbad497008d3a3ff016964719907bdb01a645"/>
+  <int value="41"
+      label="cb6e91711ad6d55c8906f379cb071fb5c47933654a7415612eee6629f26fbcd7"/>
+  <int value="42"
+      label="76ee8590374c715437bbca6bba6028eadde2dc6dbbb8c3f610e851f11d1ab7f5"/>
+  <int value="43"
+      label="c746127c5f6b529ce9e2948efd9465444089319acf03f34d0bf37eadc77db22f"/>
+  <int value="44"
+      label="952c2039c0243eb515dd73d83fc3643184874feb0862a9837731ed9b4742e17a"/>
+  <int value="45"
+      label="1069fa47a0aa4f8cf7111b1caea365eeaed10bfff32660def6e0614bfae70875"/>
+  <int value="46"
+      label="d1de2ae61c8df2fa623966163d4c73d460bfc428e57585be6bfeb9a56323d1b6"/>
+  <int value="47"
+      label="4002fcd311d07331567e71bcd971e46048c8dce8d1659711753b3daa2a269afa"/>
+  <int value="48"
+      label="b2def5362ad3facd04bd29047a43844f767034ea4892f80e56bee690243e2502"/>
+  <int value="49"
+      label="9318226f8c83afe47f5f47c24f59ce12dba8c73b181bee6b2ea1f40a06bc1869"/>
+  <int value="50"
+      label="967b0cd93fcef7f27ce2c245767ae9b05a776b0649f9965b6290968469686872"/>
+  <int value="51"
+      label="44af8afcf1395d2a8e30ef812ce19ceb2e8948dfd21e00fbaa34689f9a24721f"/>
+  <int value="52"
+      label="17755a5c295f3d2d72e6f031a1f07f400c588b9e582b22f17eae31a1590d1185"/>
+  <int value="53"
+      label="86c13a3408dd1aa77ee8b6947c03958772f531248c1627befb2c4f4b04d04496"/>
+  <int value="54"
+      label="ff5680cd73a5703da04817a075fd462506a73506c4b81a1583ef549478d26476"/>
+  <int value="55"
+      label="006d7be7555dd82026442c4f1a27a80e89a1989cb87b34448ed2194c18196d5e"/>
+  <int value="56"
+      label="43cffc359f2e8caa57388ee9f6f1dbe93bf093682a699ac3852e6d1f8579e7f9"/>
+  <int value="57"
+      label="be3db7b79bfe579dcf9b07ca4cad75aff16975568e5b45cfcae4d61fb63175a8"/>
+  <int value="58"
+      label="5192438ec369d7ee0ce71f5c6db75f941efbf72e58441715e99eab04c2c8acee"/>
+  <int value="59"
+      label="25d4913cf587097414d29d26f6c1b1942cd6d64eaf45d0fcf81526adba96d324"/>
+  <int value="60"
+      label="f48badd7df6a06690d0ae31373b12855f8dedb14517f362a313101cc98cc6b35"/>
+  <int value="61"
+      label="25aeec63f3ccd73dd61cb4fbbd13603722e02cb54e03047737084211071d7850"/>
+  <int value="62"
+      label="10ba3485ca8bb6880ab9531a4063e4001555561c7f2e055165f49b2d74fc5f6b"/>
+  <int value="63"
+      label="1906c6124dbb438578d00e066d5054c6c37f0fa6028c05545e0994eddaec8629"/>
+  <int value="64"
+      label="23f2edff3ede90259a9e30f40af8f912a5e5b3694e6938440341f6060e014ffa"/>
+  <int value="65"
+      label="9adb99c93ab256ecca2b5350c75048a8584c12dfc248e3f60ea9354c34ebfcce"/>
+  <int value="66"
+      label="9736ac3b25d16c45a45418a964578156480a8cc434541ddc5dd59233229868de"/>
+  <int value="67"
+      label="a6e11ff15ec326a5e3f18ad33a056694dc84c699766d028a5ad0efe1a8e53ac7"/>
+  <int value="68"
+      label="b638cff05c8a832758edc3028af9e2d55514568bc6bb34ab36d140b97ac6b12d"/>
+  <int value="69"
+      label="023c81cce8e7c64fa942d3c15048707d35d9bb5b87f4f544c5bf1bc5643af2fa"/>
+  <int value="70"
+      label="a6f1f9bf8a0a9ddc080fb49b1efc3d1a1c2c32dc0e136a5b00c97316f2a3dc11"/>
+  <int value="71"
+      label="bd153ed7b0434f6886b17bce8bbe84ed340c7132d702a8f4fa318f756ecbd6f3"/>
+  <int value="72"
+      label="b1124142a5a1a5a28819c735340eff8c9e2f8168fee3ba187f253bc1a392d7e2"/>
+  <int value="73"
+      label="051cf9fa95e40e9b83edaeda6961f6168c7879c4660172479cdd51ab03cea62b"/>
+  <int value="74"
+      label="36ecc61fc7e5f1923d167e67dfde34608549b34a63c7c6e60ffd5c1840381f5c"/>
+  <int value="75"
+      label="87af34d66fb3f2fdf36e09111e9aba2f6f44b207f3863f3d0b54b25023909aa5"/>
+  <int value="76"
+      label="9392ae2149924ade37e645dba1ff4bdddcda2b291b6097669d2afa5c7a372619"/>
+  <int value="77"
+      label="8fd112c3c8370f147d5ccd3a7d865eb8dd540783bac69fc60088e3743ff33378"/>
+  <int value="78"
+      label="0656f5955204c8d2bc8b1ca475e2a4fa6e124d124512784157c858b55471141a"/>
+  <int value="79"
+      label="495a96ba6bad782407bd521a00bace657bb355555e4bb7f8146c71bba57e7ace"/>
+  <int value="80"
+      label="5a889647220e54d6bd8a16817224520bb5c78e58984bd570506388b9de0f075f"/>
+  <int value="81"
+      label="5955ae291574a931342cf7450e16652ede1e0fb3097e1571dfac11c915601564"/>
+  <int value="82"
+      label="b4a039eafc4310ba9bde093edb8f9d9d0b3d4c7c004d48288c35dbcc19467d18"/>
+  <int value="83"
+      label="2a29337c3d6224cc53f0bb5e5d5820c0d8848b04871328f090fee3cd6bf821b4"/>
+  <int value="84"
+      label="808d68b3fab4884a5f971ace7d10550d7a95a163774f3ec36afffb213fbe4c74"/>
+  <int value="85"
+      label="94072ad3f58f70f93098e5a5f6c04c96c710bd849d83184919ae90eb890ae400"/>
+  <int value="86"
+      label="7caa03465124590c601e567e52148e952c0cffe89000530fe0d95b6d50eaae41"/>
+  <int value="87"
+      label="dbc1e3a15238a0483bcdb8fdec616e03e705a48e2a501157cadf3b9c7311c5e5"/>
+  <int value="88"
+      label="1f4224cec84fc99ced881ff6fcfd3e21f8c519c547aa6a5dd3de247302ce50d1"/>
+  <int value="89"
+      label="e7ca91bbfbb18788057b3a8070446ea5291160194102f7dcc3b9848c63cb9cd5"/>
+  <int value="90"
+      label="56174d3ad971a8944964b189811f3008493a6a90422e3c5804ec838d4f94f622"/>
+  <int value="91"
+      label="0c7acaa710226720bbc940349ee2e6148652a89dbf406a232c895f6dc78ebb9a"/>
+  <int value="92"
+      label="702116ccd8bf23e16466f0e0dba0ed6a239a9c1cd6a8f5a66b39af3595020385"/>
+  <int value="93"
+      label="aa2630a7b617b04d0a294bab7a8caaa5016e6dbe604837a83a85719fab667eb5"/>
+  <int value="94"
+      label="36c22314131a5fbf1b70ea4ccf4bc13a777d938ec65e1da24e3c2cfd01d3d163"/>
+  <int value="95"
+      label="4905466623ab4178be92ac5cbd6584f7a1e17f27652d5a85af89504ea239aaaa"/>
+  <int value="96"
+      label="f463c54d9f1a047aed52656ac785e07ebec528e0207bfd3f55d893237668f6ae"/>
+  <int value="97"
+      label="62554c17005543b237215f04268dcd2fd1c470240ad3c8660e25ae2c59630f55"/>
+  <int value="98"
+      label="6544ff9adb642c4c3698a60d8143b6b93bcef01365b540f614dcc2a45ab94d31"/>
+  <int value="99"
+      label="927a1b8562280576d048c50321ada43d8703d2d9521a18c28b8c46cc6aae4efd"/>
+  <int value="100"
+      label="4eada9b5311e718199d98ea82b95005cba93198ab1f97efcbe8dc6201628f8af"/>
+  <int value="101"
+      label="3861d7b6961fcdb2120456ff6fc2eb7704b1a741b4bd933a8376f5e1915ca698"/>
+  <int value="102"
+      label="2a4212605aa3e8aecb0fc19806cf3b40b53b95f1a34dbbd6e3ed27230324abb3"/>
+  <int value="103"
+      label="d2a5f32f0e01b910ef4e3b46bf84e5af5fb5689e7d1507e929e368ac88c6cc76"/>
+  <int value="104"
+      label="67dc4f32fa10e7d01a79a073aa0c9e0212ec2ffc3d779e0aa7f9c0f0e1c2c893"/>
+  <int value="105"
+      label="bb4128ec9620f2d2a49ce8e2c4e257aebad93a0f11c56b5fa4b00e23759fa39d"/>
+  <int value="106"
+      label="a4003bd5bdd894e01a8e01e06b62c7aa82f03de5253133570aad4fd0e7d81d3c"/>
+  <int value="107"
+      label="b21d2a743318712ba16f39919d961a4bafba3bca9a43a75b1fcfe22c5d70caba"/>
+  <int value="108"
+      label="c444b5b66ce5d71e1b5e40f27385c95cbfd24a05b56f70cac0992f0f50c3379c"/>
+  <int value="109"
+      label="2bcee858158cf5465fc9d76f0dfa312fef25a4dca8501da9b46b67d1fbfa1b64"/>
+  <int value="110"
+      label="fea2b7d645fba73d753c1ec9a7870c40e1f7b0c561e927b985bf711866e36f22"/>
+  <int value="111"
+      label="92c46879626ef2cc1ecea50c72fb5e385844095f21cbf3b283cb82e6b9fc6a58"/>
+  <int value="112"
+      label="e5ca37bc7b6c361979bc6b123ca9a1db019046d7ff5f57dfb854b19d10b0682f"/>
+  <int value="113"
+      label="2a8f2d8af0eb123898f74c866ac3fa669054e23c17bc7a95bd0234192dc635d0"/>
+  <int value="114"
+      label="093db767888f6b1327555dbd42bb5c93fedec5044c7a84bc6ea32a578c2235c0"/>
+  <int value="115"
+      label="23849d094923d44a4881b63ab185e9be15aac8ef2c3044d934bc7f26e2d2cd69"/>
+  <int value="116"
+      label="2596904dc4d699ae20c2cef4dce47f285937d77464ac370746f52dea76ba0c28"/>
+  <int value="117"
+      label="6dbfae00d37b9cd73f8fb47de65917af00e0dddf42dbceac20c17c0275ee2095"/>
+  <int value="118"
+      label="f53c22059817dd96f400651639d2f857e21070a59abed9079400d9f695506900"/>
+  <int value="119"
+      label="fac95de3c24a174194800cffaa3ca51d7116630664a9b60c8758b4ef0dc58f88"/>
+  <int value="120"
+      label="a87443b3d896eb257ccce99b95ada9bc81b9db4e3142aa9a99af0942cb0a4a3a"/>
+  <int value="121"
+      label="567b8211fd20d3d283ee0cd7ce0672cb9d99bc5b487a58c9d54ec67f77d4a8f5"/>
+  <int value="122"
+      label="ab98495276adf1ecaff28f35c53048781e5c1718dab9c8e67a504f4f6a51328f"/>
+  <int value="123"
+      label="fd872d176617e50c266119d0fdb047b0732da2048b121af7b9860ca3e2f2f2be"/>
+  <int value="124"
+      label="c1ad1b1898ec395048df070bfa217e25c913bed8ca6b73de085528846a0103c1"/>
+  <int value="125"
+      label="3219b09114ff495a3eb6eb00c2efeab34002ae5f0a56c7679ea087a3fa037e4f"/>
+  <int value="126"
+      label="67ea193243ae383939b5ad9e356a6b2bf93a93bcdcf828a47082497883083f86"/>
+  <int value="127"
+      label="77290717614b25f12964ebdb38b5f83caadc0f6c36b0777f880fc6dee1d339cc"/>
+  <int value="128"
+      label="3b0d73b4be4a854adc3e51d7ef9fa48aefbb2cdd824d67bdc7d7d09a2abc2d43"/>
+  <int value="129"
+      label="effee1f1e5f39f42ff80d471c9c5a799a8c843f9b676315f9eab3f4c7a2f7fc8"/>
+  <int value="130"
+      label="3380709af3b096be3cc2a40548142c0a520028db09e2cb77ae2206616ab6cbb4"/>
+  <int value="131"
+      label="4bdc636f48d21fb68c5a3cd4a20685788043bdb524e7e84d4192c451ee3429b5"/>
+  <int value="132"
+      label="d0773adb60043e954309d9714fe053eaad8aa5b9586edba468e276df82065adf"/>
+  <int value="133"
+      label="ff342fb6c4c8bd30a4706f73489539f19e6e48cc05f46254654f6610dbc540e9"/>
+  <int value="134"
+      label="c7f43b4cf5b71568294f822b53762605f6ddd15cadece739e9e2c3cba61e9d67"/>
+  <int value="135"
+      label="9c6f6a123cbaa4ee34dbeceee24c97d738878cb423f3c2273903424f5d1f6dd5"/>
+  <int value="136"
+      label="052b687107ec84e8730382452ec2a27451745d7485a57d6f464e0da7a1b6af2a"/>
+  <int value="137"
+      label="6c464b9a5b233a5e874da765c26f045010d2ddcff45794f0b4c7e4aafa501495"/>
+  <int value="138"
+      label="3499f93fd394523bfb1ec4c3ad4dfb310131fbe9ee5476bde6295de808d5dd8f"/>
+  <int value="139"
+      label="9699225c5de52e56cdd32df2e96d1cfea5aa3ca0bb52cd8933c23b5c27443820"/>
+  <int value="140"
+      label="26c18dc6eea6f632f676bceba1d8c2b48352f29c2d5fcda878e09dcb832dd6e5"/>
+  <int value="141"
+      label="616167201433aea6c8e5e3070afcaf6749188f814bd1abb179ae8dad3abf26ec"/>
+  <int value="142"
+      label="b0f6f15b4817ebe6fe0b4bfcd7d3ace4c758b0ab6f8a9da2ed92e618239d9c98"/>
+  <int value="143"
+      label="3a803e7c0a43a29fd73672e3d0bb2c3653d948ede0b3cb1db4ce75a857e89af1"/>
+  <int value="144"
+      label="9ecc51368e86e3460f66c295e4942dd53080f27b1e410aff2d1aa9d4e6bc7e7c"/>
+  <int value="145"
+      label="8a2affbd1a1c5d1bdccbb7f548ba995f966806b3fd0c3a00fae2e52f3c853989"/>
+  <int value="146"
+      label="1528397da212890a830b0b95a59968cef234773779df5181cf10fa647534bb65"/>
+  <int value="147"
+      label="31de0cb19f2adbb0d1cd7b1b31ef8ee3eb59b74459aef94b480beeeeb85c64c9"/>
+  <int value="148"
+      label="cf0b474ace8469faba402f02eebdf9e1700d9cbe8be4e4348407b69dd3196e94"/>
+  <int value="149"
+      label="980922eee07f86bc7f5e5e95d57db8bdae68e17a421c4e72a96a708a87920124"/>
+  <int value="150"
+      label="3551de58a7d79cd980283df81790d63a982c1a63b30482ec5821db7661554ef9"/>
+  <int value="151"
+      label="6f3e077fe5504646c0191afce494e4eb68183e398f5a4dc05669f8b6e6e682fe"/>
+  <int value="152"
+      label="25b41b506e4930952823a6eb9f1d31def645ea38a5c6c6a96d71957e384df058"/>
+  <int value="153"
+      label="d8fb33e385c9c2da729a84706ba927dcbb79273e122ffd9673363b70b7f36cbb"/>
+  <int value="154"
+      label="510d20e5c47f63cf666b20f61af62bc099a42ac824ffa443a2da7c90b1808a91"/>
+  <int value="155"
+      label="4d40e7af4304a09de87fbf9896204c055141e3f809b2fe733bb2310fdf98a162"/>
+  <int value="156"
+      label="4462c107c485dd6a5443f5e7a1604416034a374c3f4d10875f1c3715027563af"/>
+  <int value="157"
+      label="04a6ea654b23658973c98198c64a3a691c0da72ebebd9aebf75324cde6960eaa"/>
+  <int value="158"
+      label="fc3b82796b572ca9731993635db8cf07c2bf01e199b2f273a3f953bd185de3c0"/>
+  <int value="159"
+      label="5e7673a17a08d61413cd51b57dbaacbebfe5acb915e3966e5321b13eb9efaaeb"/>
+  <int value="160"
+      label="ab5cdb3356397356d6e691973c25b8618b65d76a90486ea7a8a5c17767f4673a"/>
+  <int value="161"
+      label="2a8bed32ae680d2d187b9a7afd171d83fd0b935eaf9e2c1b43e80278d2063e39"/>
+  <int value="162"
+      label="1916f3508ec3fad795f8dc4bd316f9c6085a64de3c4153ac6d62d5ea19515d39"/>
+  <int value="163"
+      label="278a6391d3d36b49aa4080f56a36b3c10fba4e28aa6a9592a82e7535113a12d3"/>
+  <int value="164"
+      label="5f665b4060be9efaf6ad739f6b39a1db9847277eb8dc144045376de1009e3127"/>
+  <int value="165"
+      label="16d82d67a1ed8e89f9ab58f7d0fd3eb0d0017687fcaeecd40475f10083a5b593"/>
+  <int value="166"
+      label="81a98fc788c35f557645a95224e50cd1dac8ffb209dc1e5688aa29205f132218"/>
+  <int value="167"
+      label="c07135f6b452398264a4776dbd0a6a307c60a36f967bd26321dcb817b5c0c481"/>
+  <int value="168"
+      label="db15c0062b520f318a19dacfecd64f9e7a3fbe609fd586796f20ae028e8e3058"/>
+  <int value="169"
+      label="4a49edbd2f8f8230bd5592b313573fe1c172a45fa98011cc1eddbb36ade3fce5"/>
+  <int value="170"
+      label="86a68f050034126a540d39db2c5f917ef66a94fb9619fa1ecd827cea46ba0cb0"/>
+  <int value="171"
+      label="f1c6ba670cfc88e4df52973cae420f0a089dd474144fe5806c420064e1591229"/>
+  <int value="172"
+      label="d6a18443d348db994f934ccd8e635d833a27ac1e56f8afaf7c97cb4f43eab68b"/>
+  <int value="173"
+      label="59df317bfa9f4f0ab7ca514d7772296aa2c765b87664d08b96e57399e364729c"/>
+  <int value="174"
+      label="15eed339594b304f8cf847b477371d8d6fec61f4db2b01af589e7c53b35cae4c"/>
+  <int value="175"
+      label="8bb593a93be1d0e8a822bb887c547890c3e706aad2dab76254f97fb36b82fc26"/>
+  <int value="176"
+      label="6106c0e3a0a299831875127bd7d3cc1859803d511cac11eb6e0840dd166fc10e"/>
+  <int value="177"
+      label="f3438e23b3ce532522facf307923f58fd18608e9ba7addc30e952b43c49616c3"/>
+  <int value="178"
+      label="b94c198300cec5c057ad0727b70bbe91816992256439a7b32f4598119dda9c97"/>
+  <int value="179"
+      label="2021917e98263945c859c43f1d73cb4139053c414fa03ca3bc7ee88614298f3b"/>
+  <int value="180"
+      label="08b3a6335fce5ef48f8f0e543986c07fd18a3b1226129f61864bbd5bdd1f1cc9"/>
+  <int value="181"
+      label="7e0ead76bb6819dc2f54511a84354f6e8b307b9dd82058ea6c004f01d9dda5df"/>
+  <int value="182"
+      label="c784333d20bcd742b9fdc3236f4e509b8937070e73067e254dd3bf9c45bf4dde"/>
+  <int value="183"
+      label="82b5f84daf47a59c7ab521e4982aefa40a53406a3aec26039efa6b2e0e7244c1"/>
+  <int value="184"
+      label="4b72dfed3edccb5f4945682e295731a0864ac6b5b85b193ecd2f06b4900c1cfd"/>
+  <int value="185"
+      label="951ee046fa83316e6786c08c44f13b4ca2ead2d2644d63314391c0cc70887d0d"/>
+  <int value="186"
+      label="58dd61feb36ea7d258724371709149cb121337864cacb2d0999ad20739d06477"/>
+  <int value="187"
+      label="4223894003a881c5df6bab163db235c221a18d54bf759945820e670da82e3f39"/>
+  <int value="188"
+      label="4a2659666dc0203b916f53d80ad8f61ac30bea161f485cc7527e6a5937e49216"/>
+  <int value="189"
+      label="dd5ed1c090f9f448061baa94a6bb11017544e9eefaa20cc714ce6c633f5dc629"/>
+  <int value="190"
+      label="07e854f26a7cbd389927aa041bfef1b6cd21dd143818ad947dc655a9e587fe88"/>
+  <int value="191"
+      label="6b1a505e0246f2f60c490ff0c097a7be27210cbb7500237f88b0cd48298bc9b8"/>
+  <int value="192"
+      label="381a3fc7a8b082fa28613a4d07f2c7553f4e1918ee07caa9e8b7cede5a9ca06a"/>
+  <int value="193"
+      label="6e364b6133deefdcbb21273c5f445a20afbc05038d5b021c0c2153039016345b"/>
+  <int value="194"
+      label="6b3b57e9ec88d1bb3d01637ff33c7698b3c9758255e9f01ea9178f3e7f3b2b52"/>
+  <int value="195"
+      label="7aedddf36b18f8acb7379fe1ce183212b2350d0788abe0e82457be9badad6d54"/>
+  <int value="196"
+      label="149f2ee63b9a5e5803240a770dc991fc2e3445e62831c245a49bc4f1f738ff9c"/>
+  <int value="197"
+      label="ec9056fe9509411609763aee831ef37c832b75b3d727528fc7c75201c1ff28e6"/>
+  <int value="198"
+      label="675605f1567e25fbd2526befea2aefbdb2279f3e1baa3a303ae7555d1bda3ee4"/>
+  <int value="199"
+      label="891ff898e4a8d555140056e3176eea91f4d808ee7f6d1bfbcce6f84807639f91"/>
+  <int value="200"
+      label="0b9fa5a59eed715c26c1020c711b4f6ec42d58b0015e14337a39dad301c5afc3"/>
+  <int value="201"
+      label="bb52086d0639e8db332775ac8f4e8435d92ceb00f4e24f28fc0eabe240772e80"/>
+  <int value="202"
+      label="6d6f0c340971a218a31d10330ea9ae7c7a6550534c6eefeddd2118e114db473e"/>
+  <int value="203"
+      label="5375662628fa0a6840aec8c592bf5d8de564ed3efb62c7c932fca8d754d9bbd6"/>
+  <int value="204"
+      label="50cc86ba96db3263c79a43ead07553d9f56659e6907e72d8c026637a1cdc85dc"/>
+  <int value="205"
+      label="36abc32656acfc645c61b71613c4bf21c787f5cabbee48348d58597803d7abc9"/>
+  <int value="206"
+      label="2fc5667a4b9a2678ed6ac6ad25465fcbf6094bfcd9504097c7a8fa47ade5e888"/>
+  <int value="207"
+      label="b738290cc08547e79ac67f831ebb33547c4e7db4514e2d2988c23c441340eb41"/>
+  <int value="208"
+      label="f7ecded5c66047d28ed6466b543c40e0743abe81d109254dcf845d4c2c7853c5"/>
+  <int value="209"
+      label="7f4296fc5b6a4e3b35d3c369623e364ab1af381d8fa7121533c9d6c633ea2461"/>
+  <int value="210"
+      label="fbe3018031f9586bcbf41727e417b7d1c45c2f47f93be372a17b96b50757d5a2"/>
+  <int value="211"
+      label="b1be0f7a5e638b559d8b521fef6017ad8fa16eb0548e846b2ac4b41d89b41f14"/>
+  <int value="212"
+      label="e43dea894f42cecf4a1dd60ed1dab82f7c0a308ae32a3d49a7aa1a3e957015f7"/>
+  <int value="213"
+      label="c5697be91cd655539b560758e91b6e085461623741034c485e47d7e9d25a03c0"/>
+  <int value="214"
+      label="80dbfb97bdd3926baee41f73c5588faa17d707b03adf4907a2bc677f3ef1717c"/>
+  <int value="215"
+      label="eb4993efa9b089e593418aa893f8e93a7374d810e52fcbe01e7f1d7e92a6d024"/>
+  <int value="216"
+      label="674039e472561963c8cb00d21a97a90a18bb8a1c4c317ac67e382a652bb573c0"/>
+  <int value="217"
+      label="9b219d0fbff36a5fb32090571906bceea68617c833a3f61b81e962a8e64db8af"/>
+  <int value="218"
+      label="da8796be34cc81abee7304c4d2bca0ac984c5b24b61b13e2285e1d27ad8cebf0"/>
+  <int value="219"
+      label="ede4b1535a529bf1606bc6ff757b91470aa30aeaffd2d6df2eba340dae302fca"/>
+  <int value="220"
+      label="a7a8f039894f5f675e92a778e008e424c9417dba06a1738b45b4e08d36fc2d7c"/>
+  <int value="221"
+      label="659cb368ac56998bd07af2cafc5fb93f8e79474accc2a6cf1ac9f2192d136360"/>
+  <int value="222"
+      label="f8e5f905bc939911267b83d50814a90323b51e183629db52d4fc2d5468a5a578"/>
+  <int value="223"
+      label="98ca29f313386721afbf5d14f1abcaa1dc63cc8d1fd7dc361f6b01368938f24b"/>
+  <int value="224"
+      label="915086ccd4ed1ea749b427f6b0ceb4a0ef5b4a1cf18070539c0f2a758185a382"/>
+  <int value="225"
+      label="3fab784fc3c9ab9eedc12ecdc0db550f4c3dbfd3e86d78815333c5eba518cb9d"/>
+  <int value="226"
+      label="22076e5aef44bb9a416a28b7d1c44322d7059f60feffa5caf6c5be8447891303"/>
+  <int value="227"
+      label="7006a38311e58fb193484233218210c66125a0e4a826aed539ac561dfbfbd903"/>
+  <int value="228"
+      label="8ed5b4c041b6b293c0e6413015066d318483c901ff69e86a521d0cb25569f3e8"/>
+  <int value="229"
+      label="16a9e012d32329f282b10bbf57c7c0b42ae80f6ac9542eb409bc1c2cde50d322"/>
+  <int value="230"
+      label="da800b80b2a87d399e66fa19d72fdf49983b47d8cf322c7c79503a0c7e28feaf"/>
+  <int value="231"
+      label="68c3692214724d4b55a760f470b4fca8b5e0fe1d729cff22feb4ca88acd39809"/>
+  <int value="232"
+      label="c06c872fc2d0ac08d78d421981fbda4e35500d0946f79894edd21ac29dec0719"/>
+  <int value="233"
+      label="33af58b5589ecea7926252477838ba40247ab37b6fb39e34fcbd552cd5a8c66d"/>
+  <int value="234"
+      label="8adb238554a0cbfc3a11fecc183e3cd2c23d25e7894cf2bbae58eb70a44e7cf3"/>
+  <int value="235"
+      label="98b3f10a025041910f197cf17ca0fcdfed75fb2c8c14a843e04d5656c9ebac1a"/>
+  <int value="236"
+      label="dd9a6bfbf44e17a27f368ac8e067b307396269a747f92e8f2acf2b451e3ffc72"/>
+  <int value="237"
+      label="309f13d49ea66f523241b55524744464e28cc1b82ef79b64e4d581880dcd771f"/>
+  <int value="238"
+      label="98008e2edbb72bad42da2fcb06ac1aaa0b2e6e0c72e8ca204fbafd1bb4879441"/>
+  <int value="239"
+      label="8e8b56f5918a25bd85dce76663fd94cc23690f10ea9586613171c6f8378890d5"/>
+  <int value="240"
+      label="a25a7214c2b6c86142ada39dff2d73d865aa57843fdd2db77b3febf82683de2d"/>
+  <int value="241"
+      label="2896b4ddbe61457183cc7ed27bd78ac50a207f6901c5c52e53dc1676f9bb1e06"/>
+  <int value="242"
+      label="719cf5b36192e7bde650cc91341e6f649dbb8c3ee48bacaa97fa0e05b6374b41"/>
+  <int value="243"
+      label="bcce8e2bbaee71b6358ddd641cbbfc25de454003006271f75b50b726d67c3bc9"/>
+  <int value="244"
+      label="1c294bc25243768913ed4ad5ed61cb02bfbae0bce6e6e72e5f9658f346b42496"/>
+  <int value="245"
+      label="3bde97686e3af51d3f572c4888c12bd1d1e097f12f49ec3c92896551e36f0085"/>
+  <int value="246"
+      label="93a9b3c96aae1cd661215d0c2a065da963d7160d1c694621bcb28c406df64db2"/>
+  <int value="247"
+      label="f6146bc238e8fce0d47b7074c9a26b1aa0f883528510f06d9cfec41ff6ca1968"/>
+  <int value="248"
+      label="2dc9470be63ef4acf1bd828609402bb7b87bd99638a643934e88682d1be8c308"/>
+  <int value="249"
+      label="860a7f19210d5ead057a78532b80951453cb2907315f3ba7aa47b69897d70f3f"/>
+  <int value="250"
+      label="0bdd5abe940caaabe8b2bba88348fb6f4aa4cc84436f880bece66b48bda913d8"/>
+  <int value="251"
+      label="006cb226a772c7182d7772383e373f0f229e7dfe3444810a8d6e50905d20d661"/>
+  <int value="252"
+      label="aa1c2bedb1a508baad7fb3f5e02897b907c748dea9b7908904aadbd0497aab6a"/>
+  <int value="253"
+      label="d9c473cee25f94d1bc6062bd62911477276f064b827a944e064f85d0912d2c5e"/>
+  <int value="254"
+      label="31512680233f5f2a1f29437f56d4988cf0afc41cc6c5da6275928e9c0beade27"/>
+  <int value="255"
+      label="d2f91a04e3a61d4ead7848c8d43b5e1152d885727489bc65738b67c0a22785a7"/>
+  <int value="256"
+      label="3027a298fa57314dc0e3dd1019411b8f404c43c3f934ce3bdf856512c80aa15c"/>
+  <int value="257"
+      label="af207c61fd9c7cf92c2afe8154282dc3f2cbf32f75cd172814c52b03b7ebc258"/>
+  <int value="258"
+      label="809f2baae35afb4f36bd6476ce75c2001077901b6af5c4dab82e188c6b95c1a1"/>
+  <int value="259"
+      label="95735473bd67a3b95a8d5f90c5a21ace1e0d7947320674d4ab847972b91544d2"/>
+  <int value="260"
+      label="a51a2f3a050e838a5050696578dbbedaac1a107ee2d9d48fae505d18d0da5cf8"/>
+  <int value="261"
+      label="6b86de96a658a56820a4f35d90db6c3efdd574ce94b909cb0d7ff17c3c189d83"/>
+  <int value="262"
+      label="ab39a4b025955691a40269f353fa1d5cb94eaf6c7ea9808484bbbb62fd9f68f3"/>
+  <int value="263"
+      label="479d130bf3fc61dc2f1d508d239a13276ae7b3c9841011a02c1402c7e677bd5f"/>
+  <int value="264"
+      label="2dee5171596ab8f3cd3c7635fea8e6c3006aa9e31db39d03a7480ddb2428a33e"/>
+  <int value="265"
+      label="ab3876c3da5de0c9cf6736868ee5b88bf9ba1dff9c9d72d2fe5a8d2f78302166"/>
+  <int value="266"
+      label="47c7a149ca82fa7ba940a4d711d010625c6cb0b748b17016c46e25ce7acd2b0c"/>
+  <int value="267"
+      label="cc4997863c8c48a4cb5c3e6537dc06028d8638be49f5f8a2ba56f2f2c8a8c779"/>
+  <int value="268"
+      label="a86bdab8f480b6eb8942ab9170bdd0991971a7ad135dfbbcb7285f07a7d1e38a"/>
+  <int value="269"
+      label="2da8f9ea3454d21146464a3f9d028dc4c7fbb57b1c52c73c2b0572a2f599a2d3"/>
+  <int value="270"
+      label="0fe14c264b17bb6f0d653e7a70eb363dbf54be158039eddae5c25711df48c103"/>
+  <int value="271"
+      label="5efa073f49426344483ab0ddbbdda5e35972f9c47c74ddf98ec42290b251ca97"/>
+  <int value="272"
+      label="2e00915a9f7be06ab2370c7b7c200c0a96d5ac6a50ce1874dbefde4022d4de8e"/>
+  <int value="273"
+      label="85d26be90d934fccdb4ff7b38d8c79ca7652b816d6a52446ca8428a6b85dc57c"/>
+  <int value="274"
+      label="7f1dec8b0319548a056de5bb521bd93eb74e6a76f28dffb75b45a53b775af7ab"/>
+  <int value="275"
+      label="8a903b600a080b38dfe20dfb6acd23122f64620e5808b9fc8688952fc1a3559c"/>
+  <int value="276"
+      label="84aac093e08c49dbfff8e560759248dbe67135b372b23d2a881d5f99cbb191e8"/>
+  <int value="277"
+      label="6c5cbf02c1849166278f1cd1c83583a147fb7bc95e289b276366935e3153f302"/>
+  <int value="278"
+      label="482f76a2a9346dbb077619bbe1efecd54107e992ff4e8f4d70a39e2405d939d4"/>
+  <int value="279"
+      label="3a6c24e80f681d8b1047cec051c27594f885ba0887a26379092dfef506160e9b"/>
+  <int value="280"
+      label="30ab1bcd7bed1ff2679f71228820420a7063c6cead7ec30d4a016154876dddb5"/>
+  <int value="281"
+      label="ae56d847973d199390e66e4024c9f87d87371e8ba8876af83d1e644f54664738"/>
+  <int value="282"
+      label="93657f8530c596bf909e50da7d8d9cbb36b824cc16ab589137e1438011bc9901"/>
+  <int value="283"
+      label="01d0d8e07bc5a92da7e7b81e9a569fe3a2d63a997dac596002c5dc810cad17bd"/>
+  <int value="284"
+      label="4cc29758a2cb9b50109987f37537cf0c55ba2e6798937307a00296b01dffe44a"/>
+  <int value="285"
+      label="49b80685d332e072c0e7b720032647e842106104e0b1139ab9e811bfb11ec034"/>
+  <int value="286"
+      label="c5ea259c629803508649f02177f63c32fa85cc4ad5c35f0d541c45df10a49fd7"/>
+  <int value="287"
+      label="55e00be277ceb0545299f24fd9f877e2acf32852db43ffcd29bca74b39b4c9fa"/>
+  <int value="288"
+      label="ceb19411c65052c757f941eb826c96941e4d08d096c7db7e7ea3c4f8c13f1a13"/>
+  <int value="289"
+      label="ea87f462deefffbd7775aa2a4b7e0fcb91c22eee6df69ed90100ccc73b311476"/>
+  <int value="290"
+      label="c63d68c648a18b77641c427a669d61c9768a55f4fcd0322eac96c57700299cf1"/>
+  <int value="291"
+      label="7afe4b071a2f1f46f8ba944a26d584d5960b92fb48c3ba1b7cab84905f32aacd"/>
+  <int value="292"
+      label="d1c45377ebdcd618cd1651dc2e02c21d751e5aa9fcd1b3431ff6ecf6a31348fa"/>
+  <int value="293"
+      label="a320f4d534d7be97c1ae8dd0499735bc895c323add2d388bfccf662c23d7f99a"/>
+  <int value="294"
+      label="7cd67c248f69d83fc2f9bb01dcb1f7ad67a363d046043796d0984c3a231f6bb0"/>
+  <int value="295"
+      label="348767cdad3bdd28b2b8dd5351aec30c68cec5cd69d276df3827dbc4f5806464"/>
+  <int value="296"
+      label="5dee74cc343db93f8deaf9e41fbc65b334254b5b23b568fa2814db8b7321ac85"/>
+  <int value="297"
+      label="ea2f9e087eaebbdfc0569eca18364e5236254624854f92e37871b5ee36744883"/>
+  <int value="298"
+      label="805c6696266b96b147468a321eba9eb8b5968f2c477cdd95fdadd1fc63dd614b"/>
+  <int value="299"
+      label="991b5ed1b2fd364b9f634b624b305203f29908be318ef6399222d8a3ef7990e5"/>
+  <int value="300"
+      label="161e83ea32d47641e23cbe0eb413a3e0b06859922a49d1a20cfa05a41e280cfc"/>
+  <int value="301"
+      label="a7e39bd7df609bef3262bf3db4dc8f3814e0db5a7a52156a6d0c35b4dae8a6ad"/>
+  <int value="302"
+      label="06c7bd9553f710e058eb27b15d47dd62d7fd4352d91da96e1efc50e15354b8d7"/>
+  <int value="303"
+      label="3a0d885cb346d8f01fd300af1546f6355c00690e340ed98f346e77b574be3fd8"/>
+  <int value="304"
+      label="1a421223e89bd87c403b48fa616948470d0f2c21ce2ac7bdd22755061c62ba92"/>
+  <int value="305"
+      label="a5204dbb2754b97e3c8a104eacb374a6498a438773c75077f0063c2ceb25d2a2"/>
+  <int value="306"
+      label="7d434d1dada2a154d49f473e381310b83ee58d290a13455182d77f1962df55ee"/>
+  <int value="307"
+      label="a378419d1ae9ebd27b22948044c684ba29bc084b98f965be73262f0f6aaa1c6f"/>
+  <int value="308"
+      label="c954c2c0b189825bb65ddb3ddca080b7dbcfe6b17cade1022bada818336677d0"/>
+  <int value="309"
+      label="05ec0897b21995a4a9899f8fcb06601ade61c04389969d138fe32cd6cfc746ab"/>
+  <int value="310"
+      label="a12574f4eb7395cc630a15fec8db1c7c828f66699d984c8c897eca44c808f55d"/>
+  <int value="311"
+      label="2bb5c28a34c9a37dd9604500ca9b3038d00528b474773a2732aea79e4905c234"/>
+  <int value="312"
+      label="b9182f52af0dd18e3a99ebbae7883d4e4cc7fe2f81fad0d36ca661efc32d0a92"/>
+  <int value="313"
+      label="df530bac9fcd914c252c2fbdceddc6183d4ae8c680ad65f03e204861dd7b1c73"/>
+  <int value="314"
+      label="0d47e98588452cf0778af6af03d442721dc083660a4bb23c697441fe2bb84f9b"/>
+  <int value="315"
+      label="3c84d996722b3c1872f53ddd7717bb2fa50ebfa07b3f3b4a395335c56712fd69"/>
+  <int value="316"
+      label="96475b35acb1c9303a90bd1dbf57418f78e29af11c4de8c8cba2e5f9309e38d4"/>
+  <int value="317"
+      label="18cfa64518e916cafe985561513cab7a897a54bd23b8e26874c5c7cbd1249cfc"/>
+  <int value="318"
+      label="3c196f84e2a0c61fec18bacabd31783b574517aad8ebc6ce6d1d7dc82b3c50df"/>
+  <int value="319"
+      label="931f1cf03a6f84c30ff3ad869be3c21a410191cc98ac0afc9d4e8b89bd869ddc"/>
+  <int value="320"
+      label="522c3960328026a1e322389a8a08fedc1b86d9c2b59b33484b77f7ce790635d7"/>
+  <int value="321"
+      label="8991e219ce9f74479eafedb3535836121dd233ea768afb9d9ac8b4a22381a8d5"/>
+  <int value="322"
+      label="881a1b9edf69ade141839ae8673d31b4f4d47f126ca08a79ff065dc9a690f4a3"/>
+  <int value="323"
+      label="62a31a5c730dba674ddb25de33df143644375b49af07878a667b813491c73971"/>
+  <int value="324"
+      label="51b6ea6478687b47d963b6149059780cf08a4f02f042d61b5bd52639095ee910"/>
+  <int value="325"
+      label="6cae87c558d2441568e38270a8dd8ff484a259dc4f3ce94ccf434c1fa99811f6"/>
+  <int value="326"
+      label="d4af6c0a482310bd7c54bb7ab121916f86c0c07cd52fcac32d3844c26005115f"/>
+  <int value="327"
+      label="f6b59c8e2789a1fd5d5b253742feadc6925cb93edc345e53166e12c52ba2a601"/>
+  <int value="328"
+      label="4ba6031ca305b09e53bde3705145481d0332b651fe30370dd5254cc4d2cb32f3"/>
+  <int value="329"
+      label="0999bf900bd5c297865e21e1aade6cf6bb3a94d11ae5ea798442a4e2f813241f"/>
+  <int value="330"
+      label="1462009b2de65d6d4d39be892bd2c186490531ce6590e48fe196070d317b60b0"/>
+  <int value="331"
+      label="e26613a578e158c2a44e4fec41e6f37a0a991fe1a5fe736c303f4420a90fb50a"/>
+  <int value="332"
+      label="498bc0cd5a49b714071ec76a41661ce2f27fc39fe4168bc7b7799a0ae25f6528"/>
+  <int value="333"
+      label="9d98a1fb60538c4cc4857ff1a8c8034faf6fc592093f619994b2c813d250b864"/>
+  <int value="334"
+      label="a2dc98ca7cbbee1822b25b267bd5ca502fa7b0cf4fff0703ee6a416703f3c7ea"/>
+  <int value="335"
+      label="f5857d8862bc2ba3c9ddca3f84146dc8d81f4d579d2b387bf60065381ee641dd"/>
+  <int value="336"
+      label="9119e2f413579777954991703eee23a04523a312b5c65f7f9374aa3100ebd8e7"/>
+  <int value="337"
+      label="af6ab51b7bad1dedd533eb59332b6227d6557f20b4443216db735b92280c7a44"/>
+  <int value="338"
+      label="086dcd7bcf864aaad5ef8c1c577bb68a131e055c93f63b9c47ee26eef15be7ab"/>
+  <int value="339"
+      label="232cbe2d9e6994c1ceb7fbee23ab1657defb6b3564726f1e78951cef3a2b095d"/>
+  <int value="340"
+      label="431b79fd9355d10dc1b50dbf6a6b62d7a5b6d356541c27605255ca4ca79420c1"/>
+  <int value="341"
+      label="7c3b46d9be8f2741f980039521858e4cdd30774fb32b3b21ceea06aa79c6aac6"/>
+  <int value="342"
+      label="9dc38a9edcf82842b674da186b6d6215ab9e2ec6d72f57b08a892728c31431f3"/>
+  <int value="343"
+      label="283310819f5e09204995d8ad9ff6fc10746297b5c0ae06bdd1e1124b10a0d7ad"/>
+  <int value="344"
+      label="6046136879e56450400f7db2ecd0df1b88f667c1e3fffc52964ff9e2e48e85f5"/>
+  <int value="345"
+      label="e85fbf8b9a2ea4909dce0fb5b2fe5f5877343d27d58a410a8b237ab675a2ddaf"/>
+  <int value="346"
+      label="5aacf1b965e853010fcb2a110317d5fce3ee351e9cc95bf444a571d7b8ef9162"/>
+  <int value="347"
+      label="9546ce00e03dd61aca58c5c8dbf38a111bad6406c91d7422e7f4c40a0cb58f18"/>
+  <int value="348"
+      label="b4296d5fe60e52f3f0ff99da75af5e7e62599f99ebe0fa413f66e6b425c3d09f"/>
+  <int value="349"
+      label="7f7c88a77d4d3b44c33b3c030bc83f1a26c20d49177ca7745d91d9de17e08f14"/>
+  <int value="350"
+      label="faddde04bcf08ca8f4e22efd2afeade6bf3d850ae47be96a82d539494f120cbd"/>
+  <int value="351"
+      label="20e24a5a3393d6c3adc384faf95152e1f9aa7222774028b53c5a34ed0c6cb399"/>
+  <int value="352"
+      label="4697a5abea0070a395456fd358e91f72f227d5850933227f1e0bc79ff847bfac"/>
+  <int value="353"
+      label="463dbb9b0a26ed2616397b643125fbd29b66cf3a46fdb4384b209e78237a1aff"/>
+  <int value="354"
+      label="9e5a34b08929bc0a581c8936aafd6ab7517bb15188b4f6fc02c45906f71595b0"/>
+  <int value="355"
+      label="b3182e289ae34ddf2be643ab79c244301605fa0f1eaae6d10fb929600af84df0"/>
+  <int value="356"
+      label="a798d92f76c9c6755e5f55f86cd14aedcc0655371e27ccde0377745ce3c50013"/>
+  <int value="357"
+      label="004124ad6037fd5f3319e7a23d4d9c811f5598d66c4754155b0aaa9e8f00621f"/>
+  <int value="358"
+      label="c90d009c47eeb9f2a29ae848f5d930f2b41ef5edbc5c5695c1414345c1dd67b4"/>
+  <int value="359"
+      label="2a4f49ee7701a395ac932e444292671588ade21259ce296e194940368702ea7f"/>
+  <int value="360"
+      label="30b71c4f9122476e761e620eec42bfa5f84c493cd49bbb1834b26e555f60de40"/>
+  <int value="361"
+      label="ef53ffaf0ceb040d077f5bd80a9deef6d4507fdb6f9bcf8c3594bece7ebdb025"/>
+  <int value="362"
+      label="651bd66f5c3dc637957ef5185e4fa671c21654b1c0ea49384f44bcb256a5084c"/>
+  <int value="363"
+      label="f5e19c8e14fe755f551cec2b7113e7c98023b176ebe6c1abcf872b2a7b932304"/>
+  <int value="364"
+      label="a74b4b6a2eb55b9864c04ecb16003ff5db5b51e42cf859f95e9d0a1dd4644096"/>
+  <int value="365"
+      label="d92405c46d912a563e43287f56cd410a1cdf6367c57c9ea7c5cae039dcbcce50"/>
+  <int value="366"
+      label="86c84b1c3a66f4285af797052467e3ed236fd2986f033c02c4771be0b970482a"/>
+  <int value="367"
+      label="d1ecacca44012c3e1e6d1b39dd2968fc7fd3127aaa57ab5182a3beabccd7a3a9"/>
+  <int value="368"
+      label="3fb63c29f47bcc4e6aadb3577ce7ca8543e0bbaba553676b8fd161295bdb9011"/>
+  <int value="369"
+      label="e0ef882da48ab0b7efb0d9ba15b2717dd08f043c25ac09b56b8b57fceeb5a35d"/>
+  <int value="370"
+      label="8ab4e88556cbf864a5e9fd50171cd4ed8424e8f0801b99e236c810915950ae4b"/>
+  <int value="371"
+      label="a4b89bb70656ea498f2d9e00a497fdb9dcd20b81b8938e952bba2df9f65729c3"/>
+  <int value="372"
+      label="bedd8bc97ea86497195a078a999a237a060aebae07bc0a0b9b778982ba5f62f4"/>
+  <int value="373"
+      label="c42533d3af4998f5ad9f072521d85d472fa7ffdcfc588c8247b337dc77109389"/>
+  <int value="374"
+      label="d646f3ea2d7003fcaa77ad219136c78e024a6f2e2307dfb8cfa97a171373ecdf"/>
+  <int value="375"
+      label="8b49506a3461063ea8cc13ffce2b581de15a94b957092a93123467b89ed802e2"/>
+  <int value="376"
+      label="6d28f9e405148b69027da990815211c858841c543feced008c238021983c095a"/>
+  <int value="377"
+      label="ed1b229e0e0875021c1f1760c3407fb1d6608eda7add71a3e3275ced09690f7c"/>
+  <int value="378"
+      label="87157a7585f4d03b00a398461e164e4806e1b3f46d03afbdc9def4e4778be2e9"/>
+  <int value="379"
+      label="22050a92836481c2f3c1f8417d37447a167007ac9ba64ea228cb6a1e14c64b8b"/>
+  <int value="380"
+      label="f73be5eba536912c557fb855517ad1ee0487bd8f63498c3949164177ba06c5de"/>
+  <int value="381"
+      label="4ba24996ddee6f8e1fcec0aa9eccfd3aa5477b3ef8f5f85f0a06073f97522857"/>
+  <int value="382"
+      label="acf7ad98e6f065866e6f8cdf0ceb6f7481f6957b6dff823f6b94d79f01a61c39"/>
+  <int value="383"
+      label="ae2033b3082825a703e5a6adc3221a86854aa411db047dd5f53eb84aa14bdc01"/>
+  <int value="384"
+      label="8d775a4f93cd20c18306144f42b569fc2a897eaeaec3d3ea3cb025d1ad4d28e7"/>
+  <int value="385"
+      label="5094b73b736adf73a0cbf43e27bf14407b4a36aa363a457fce33949ceba8e649"/>
+  <int value="386"
+      label="af110f6b5ae8b767eac6e0aa273f3816e7a40a644edacb4398146356e77509d6"/>
+  <int value="387"
+      label="f7aff41b2709f175f8aba17e567b27046b2dd54bf6e7e263d3295873437b9cff"/>
+  <int value="388"
+      label="112432e4bb848c45549fcbf0c710c566d0082bbbc4e9b38e6c76ad46448128fc"/>
+  <int value="389"
+      label="7016270b60b28c6e177edebd718007dfd3310c64a737b7db01a07690c343bc27"/>
+  <int value="390"
+      label="ad304c884a5d376bd195209a14c39e07f0d3f5cf893d802b053e1b926e55d774"/>
+  <int value="391"
+      label="94b94bbf9a0726f17b0973af6d41e9fb2e7099651bcbefddd97b0a5f2aabb0dd"/>
+  <int value="392"
+      label="8a42eeadbc8b21a35c4b3aadd7dfbcbd2ed1b1da12e8c45a534da90607e564fd"/>
+  <int value="393"
+      label="ef4fa1c630f04950e0e2d10dc19f149d08ab46dec95da3131cbaea8af8ea3027"/>
+  <int value="394"
+      label="913119f2cd3f48aca74ea6443ee50e0de1202d9c54f336dc9300affe97d4577c"/>
+  <int value="395"
+      label="7e6acd853cacc6932e9b519fdad1beb515ed2a2d0025cfd398c3ac1f0dbb754b"/>
+  <int value="396"
+      label="979f6f6a8a41c421cc673473d58a6379817be73d2e524698c80ffb66a149d089"/>
+  <int value="397"
+      label="c7f584236d86395e8f6f82c010886a2c56e071a6a1c3ed2876b8a3a72c5efbb5"/>
+  <int value="398"
+      label="202665e4c5c380b4490a81773db5dba62a90db6f5be6e0e54d11992fb1e655fd"/>
+  <int value="399"
+      label="dc053d027fc186e7c41cd193af30fc09794eb9f3d9e6736dce041440d876a801"/>
+  <int value="400"
+      label="15bb28d9207e13f8bc9557dd785eba773bea944e04d7e08ff8aa55ef3194aa20"/>
+  <int value="401"
+      label="58a2a698d86fd8497d41f68e4caeb4a98874f433da913dd26c5ca44d08ff72fe"/>
+  <int value="402"
+      label="c9905b0ee01202293ca026e64f08412442c5504c06e44ca7e9726d61f20e4089"/>
+  <int value="403"
+      label="44a3d80d3f5348596d80a09842c23a39774439f8b0b919239d2a03dac5ce5213"/>
+  <int value="404"
+      label="bfe82909872e4434f115c51a56168019594d0e03dca363d9f3b4839d0babcde5"/>
+  <int value="405"
+      label="d5597ea3453a6261f5d42eb9caf5bdb4e38a1edebdb5bea6d7c0bc1a8abecab2"/>
+  <int value="406"
+      label="5143e47569a1d5fc867893e0cc412c41f55715da78e59e9f8e43770008ca42d2"/>
+  <int value="407"
+      label="9efd911d6ff46f1831111df3c54cd2611cae2398ff7386d1cb6b4f32e3337ed6"/>
+  <int value="408"
+      label="b656a4343831a2acf11eeabc3a44b97025fffba2b910da8714cf827d81be10c9"/>
+  <int value="409"
+      label="42a70984ffd399c4eaf0e702a44bef2ad8a79b8bf4648f6bb210e123fd075793"/>
+  <int value="410"
+      label="85a3d81d2ad0c79df0a79684e0e2666009a09de15760ea1d76cf0ee7b2825dbd"/>
+  <int value="411"
+      label="02376d0908ac23041cc7d666d9daf192554f7fc36317aa9cb800908616b28af8"/>
+  <int value="412"
+      label="b083ff536f7f48a9081e294a0187b53e819771402d9d4810306de031024e5f46"/>
+  <int value="413"
+      label="508f8c6178af329bb6bb753ab943d9023be796c3adbb6c5cd4664b66feeccae5"/>
+  <int value="414"
+      label="43c74262f7492662d2459bcc9899bac54a4ecc01e1a3f5e76558992b40152418"/>
+  <int value="415"
+      label="bf01c35f337113f167b4a50186765e7b1e3890af586328f185cd0d6bae813521"/>
+  <int value="416"
+      label="1eb9cf901f0858aa17c399babebbdd8cb303a4ef4e1220c493cca2f75a3f914e"/>
+  <int value="417"
+      label="19ad98de02155d7e33e9dd21f0e45610fd11d28044b8318bbebf9f6337888df0"/>
+  <int value="418"
+      label="8bea76ebd6137aff9f1ecc3c08caf1dec47db91690d5754c4e9f15232c0a2e78"/>
+  <int value="419"
+      label="1b8a89531701608c9ef3c65f5d60a948b1badb9753622a2e81c0a4a284be63cc"/>
+  <int value="420"
+      label="3ea7b5c045a99a9771e2dea8e8098ba2732d17ceee82279552feee905530f35f"/>
+  <int value="421"
+      label="6a7b1482127002f9005a87356e1dc3e00b70bbbfa795024ff8beff74c4259b75"/>
+  <int value="422"
+      label="2364d692dccae13da56ad4a07c1325dc575215ff1a071681dfca5dd6ed7c8452"/>
+  <int value="423"
+      label="816ba0bfdf5fd64d568ec0d052f71164d9e2ccae12e0219ed6cd81e7e845fb84"/>
+  <int value="424"
+      label="a1d45d06297341b1f3a735cfa38f283e6879fec06281a361e5f417cc70d29dc9"/>
+  <int value="425"
+      label="972fbc6d55bfefb1abe3758ad7d67a349bbef80c06f1d85001dfb9101b9abc1b"/>
+  <int value="426"
+      label="6a436b58d9d830e8d5b8a642505ad6b41406adcd6894d9414f7be0a1467badb7"/>
+  <int value="427"
+      label="2fcc99f5c9d00f9a20da6131dea5c027d92636d68cd9cdbe95290a3c408919e0"/>
+  <int value="428"
+      label="66b00539826a37484930191e028f62dab1cbc89b3acd472dc4e5905e47bf7364"/>
+  <int value="429"
+      label="689bf45b3083fdead55f147fd105e3cf218ad58edf3e4b301c0c5eeea6cf210d"/>
+  <int value="430"
+      label="b5ec35baab538884cfa8dd97376b102f03e53b482c64100c250722ae9b042cbc"/>
+  <int value="431"
+      label="9ea9fe274537f4f935642cde824fd77eb0e125cf118ab9b4c219f6cbf959b18d"/>
+  <int value="432"
+      label="b16cb1ba529a39e2dfd53b3ff5a79f1904614d83e31304f0278bb40b38cf7824"/>
+  <int value="433"
+      label="0f9c1299557598cf7521bcc8798420a155cec1bb23a57ac37f5120fc9a2057f8"/>
+  <int value="434"
+      label="99333c3a665cf0efbb7488b3807b8b65f87b5b29d6880f028edc28442eeae669"/>
+  <int value="435"
+      label="782d7e61e1323d2aafb877be34ee1de0c1345136d4fcb3c945937f6a67b412fe"/>
+  <int value="436"
+      label="3d8d061edcf7b3d45995ba4341328d1be7b7eb4e9d14fee70d2f18ad68bea7c5"/>
+  <int value="437"
+      label="78cf3d3c72daf91cc51b871357a551cf95b837d074c270b08facd463a8d39bb3"/>
+  <int value="438"
+      label="2d6d690c16b11853884bbea2723725267e3f9b54a6cf07ad4690ab1e7cfb75e8"/>
+  <int value="439"
+      label="8e15d426cd04898f218be2e5fe3784f375094cc435dc61ad86c4a3c01511dbe1"/>
+  <int value="440"
+      label="58044626c34c1a7b158ddb676d9e2e65443d818dab3116231e2d62ab6426a0b7"/>
+  <int value="441"
+      label="29e7fdda489e46ee486efd75acc48f251932dc9da1872b31753cd64719567aa5"/>
+  <int value="442"
+      label="111c24a243061da76e57e3b1243eda90879ffb750552395443fa8c34dc0ed737"/>
+  <int value="443"
+      label="c53dad9e53ae27ed95f0ea7a9203f7bf56eff0f8e1ce960cb4761b968342e34e"/>
+  <int value="444"
+      label="4376a99396769fd487240ee8b573ad49706a5b9473616acef38409e91586dc1e"/>
+  <int value="445"
+      label="e156445fa20c32ad00937b27d096b8963bcc863950333a877e68fa69707a03af"/>
+  <int value="446"
+      label="71ed918a7ac6d17b3849c20180b3e7334691bc5fb73377f0070afa0be789b2d1"/>
+  <int value="447"
+      label="439c19ff3edb265ef1a920f74a4802d3dd95ace024e21e5a6ce8e064dc1566cd"/>
+  <int value="448"
+      label="63f1a6f79d6e730d10432e6308194ff7bc28850adf2badf789d971385d8512ee"/>
+  <int value="449"
+      label="a4cbf48516af3160ebc62acac6e7f258609ed0891535010c16692493a9fe1fbf"/>
+  <int value="450"
+      label="b213a9cbaa9a8831ac0b3aa80e9d15856cd43a7cc2e0bac5fcb84a24751a8a78"/>
+  <int value="451"
+      label="abcadfa35ff835cb3a0a0b86400622b80d5e80c765bc027f1b1c4e0a620f5e1c"/>
+  <int value="452"
+      label="676b9ff303ede180fb95a4736fb4d3153032c014444f63a2074c41b98b51e0bd"/>
+  <int value="453"
+      label="a59d2f09c8b168cd9afa3bc3eb4db0d7a43588d523287f2b83a822eb33709170"/>
+  <int value="454"
+      label="4e6c1616637199b5077a80ad0c2248c725e576fc8a719989456bc9cafddb7524"/>
+  <int value="455"
+      label="a76e2949cb87f6236b5f68c690747587d6448ea21cfead7950084ac015190b25"/>
+  <int value="456"
+      label="0206ead163b10ea2f8620868ebd7a15f64a20250d16cd57d6e87c4fff1a2197c"/>
+  <int value="457"
+      label="49cbd83c03cabfa0713b97bc96481d035fd4ebe06f07fab5640ed9232d8110b2"/>
+  <int value="458"
+      label="33fa5a5300613d466e6f85c8051695bed5d1fad59f25e040acda0472a74f3c20"/>
+  <int value="459"
+      label="380739620e13335805eada8f9f8b81554d3bd3c0017f3632c2677669cac7a2bf"/>
+  <int value="460"
+      label="244803cfa35953385d06657ac4e5ab4f2bc0405277be662adb905e1498b1defd"/>
+  <int value="461"
+      label="3ec18dfeb894a9ea20eb2cd40c693e2a29144fe2ec60b4f7b89026040b39aebe"/>
+  <int value="462"
+      label="9962ab1699b0eb7c7e8a578bc79893042031c1158c633613199a90b9652a2a75"/>
+  <int value="463"
+      label="8e8046ec4cac015a507ce0d2d0154a4b40e8e42b3165cfa546571435112d17e5"/>
+  <int value="464"
+      label="57a742a88d3e18fc0bc611bc7976c22edc50011757512b1a7e2e1d069b3ecba0"/>
+  <int value="465"
+      label="b489ccb224b9a6b81dd274ceaf5209c252998c9a76af48e4f4c50a0728461825"/>
+  <int value="466"
+      label="42a807cec5ae9c0f03b40ca043ac70468b5219bd75cc5bbea51d921dd100156f"/>
+  <int value="467"
+      label="f42352c3cc3d84b8518989d647c88ca301c88fb991938bbcecc9ee60e565d377"/>
+  <int value="468"
+      label="5c41a73ab2c35dfcd771f6fd6e3e8fac9b469d386cadda56a95b646eb48cca34"/>
+  <int value="469"
+      label="1255cabe8152fa64df942f7a47417e29f96c1ce11bf8c84ecbe2815cc1280810"/>
+  <int value="470"
+      label="4ef7dacf77edb751f704035fb5c6c442351ec7220af90bdf82fd047bd3c24187"/>
+  <int value="471"
+      label="3329bfa13b6007ab5fc3713f0acb289426e2fbc99cc5c110a914b139571600b6"/>
+  <int value="472"
+      label="d3980aadd21638c70d74a4bb1f8ab5e11724e62ed408f9fa8d3d4d916900286b"/>
+  <int value="473"
+      label="7d6c3ebf9ea735d1854beea7cb941ab1e3503515e087bbb5be695d05f2f556e4"/>
+  <int value="474"
+      label="f2a4e6b263d0a552adff5d85dc96b5820fd66aa0b18228f48fdb087c8db34133"/>
+  <int value="475"
+      label="b89bcbb8acd474c1bea7dad65037f48dcecc9dfaa0612c3c2445956419df32fe"/>
+  <int value="476"
+      label="4f7162b974491c98585ec28fe759aa00c330d0b465190a896cc4b616231831fc"/>
+  <int value="477"
+      label="21ae412566324725ffefc1dccf88f16f8d6bf4dbbb37fe8caba47e8d66c2cdf9"/>
+  <int value="478"
+      label="9415b25dba3bbd711439e2a9964b7a5256aff3b05c772c8a34e6c93566aba63a"/>
+  <int value="479"
+      label="ac447dedd0432aab9c070f2cca01b6dab09bef07cf4ca6aaa755634f857b315a"/>
+  <int value="480"
+      label="67a84264d42e204a9a5b0a3667b951db22c505df95ed983b5e8c4d1fce77af43"/>
+  <int value="481"
+      label="3ee6b341402851b27e64021a3023aac7c1a0d2def27d5bce5c2dbeb0b22dcc71"/>
+  <int value="482"
+      label="5899d913ead119b9cdb7ba2f30efe0df68ad2cd225bdf493e8323a25aa4dbe23"/>
+  <int value="483"
+      label="871a9194f4eed5b312ff40c84c1d524aed2f778bbff25f138cf81f680a7adc67"/>
+  <int value="484"
+      label="55f77de41c03792428f8d518c55104225be43a5598d926a528ad653e1ccec7bf"/>
+  <int value="485"
+      label="4179edd981ef747477b49626408af43daa2ca7ab7f9e082c1060f84096774348"/>
+  <int value="486"
+      label="9847e5653e5e9e847516e5cb818606aa7544a19be67fd7366d506988e8d84347"/>
+  <int value="487"
+      label="682747f8ba621b87cdd3bc295ed5cabce722a1c0c0363d1d68b38928d2787f1e"/>
+  <int value="488"
+      label="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"/>
+  <int value="489"
+      label="282fb5cfbaf01518d9704de7884d7a25ff01cf882e994290d5995d5eb6c44988"/>
+  <int value="490"
+      label="fd371bea9755ff60c8828c849b8e5215de532d61b009855fa0ad630d90eef82e"/>
+  <int value="491"
+      label="d49c6f289cd056519492480f192f00a6fc7c1862dab2e7b5d8e05f6678fae141"/>
+  <int value="492"
+      label="cbad7b1d384849df0946b7ee8e7f5f7ce3aed876fda7bc9d30d8b16f29ff2c53"/>
+  <int value="493"
+      label="e0c780c629903e126f1d919570dce7c496f85f33aae66b9a3147ee75f8d1620a"/>
+  <int value="494"
+      label="376a1a7082a593dccc20d561d119e9ab8d30f11cc321d0a37fa41f0df284e01c"/>
+  <int value="495"
+      label="8d417db2dd8bf5e3084d1e3f196d583849d81bdd4c00c70b9d39369e96b8c782"/>
+  <int value="496"
+      label="b7408b4d2be0238ba37004dd34e276c6019bd2f24c9db7d4980f5f6c359a4bcc"/>
+  <int value="497"
+      label="eabc185c4e82d942b1a5978ba3c0181487d6b3b9974e5c49f72f6d0bd9637150"/>
+  <int value="498"
+      label="2541e53ba5b3b07acbe7097ac4a03e040c11cf7a6d4a67cb213d558b50167a06"/>
+  <int value="499"
+      label="68ded9a203ff6e367e12aa49977cd200f7127a800faa6f859f0bafed8286a4fb"/>
+  <int value="500"
+      label="36d7c79f3d089a0ff79972d90923dea5ca76b4ccbaf7c2751cb152e9494f52d0"/>
+  <int value="501"
+      label="be3280c6863c770a33c9040bd97d5540b216d1d91db8b088ceac1197dae1d660"/>
+  <int value="502"
+      label="c5750bf85f459fb70e2b6cd1898d375e92d7938e47a6e034cce0c12d30372ccd"/>
+  <int value="503"
+      label="22a36994f28f2fa3b16ae872a79dbb12a982da5b824d7ae434f96178ac540351"/>
+  <int value="504"
+      label="f26cdaa1c48e2d369eaf24993a424f8290983af7094a5bde9c7d44341f2e2428"/>
+  <int value="505"
+      label="c372f6d18ebee5aa23d9e919f3e6be98488ec01607df3162fc192e4b1346afb3"/>
+  <int value="506"
+      label="68aa635451d83962167e88fb08f8678d73aec66fc559462137cff9d1bc3d3871"/>
+  <int value="507"
+      label="b2f7298b52bf2c3cac4ddfe72de4d682ac58957595982f2b62301af597c699c5"/>
+  <int value="508"
+      label="35f53ce1264611e03340fe37e1ec7d4cc986c5613dca70fd04aa44545f2daf28"/>
+  <int value="509"
+      label="9091e31fe92546a5f5e1b3ed4071f4440b840c1e80dbfcba7a7ec6d5825f0b24"/>
+  <int value="510"
+      label="786ffa578618c3b9a311175e50816f4dda0605c3869f296ebc5943bf09f4e904"/>
+  <int value="511"
+      label="828b0eeff24654e8ff5841a29dd5d4e3ed30952ca43425a79283407208d39d16"/>
+  <int value="512"
+      label="497128fc90656b87290482b223efb72240fe9c421e79938de5f8110cb0be9056"/>
+  <int value="513"
+      label="2e06cae1fc20b200e6fb748557a4444bec9317dfff2e4151669e0f7944f0a9e0"/>
+  <int value="514"
+      label="122312c081949106b7049f3febf199c010ada13e3281cd358a41e7bd09c829d7"/>
+  <int value="515"
+      label="1134fd81561a2818eccfffc2e440a0cef9a40e2926c08299804d738b0a97f63d"/>
+  <int value="516"
+      label="79caaf5347e6e4a94c8e78a98496fc74020f809ede13f220fab6104c8ded329f"/>
+  <int value="517"
+      label="fde8999a5e427319835c89a17d64a2dcd13a851c0916c4c547b6d8f7a6437d94"/>
+  <int value="518"
+      label="453b74809b69019627f2f843001db5950cdd1d45371053e7f3dfdbc3714113c6"/>
+  <int value="519"
+      label="1f3c9fd4fdbb50a055bcca7fe5a581a92099cef1e9e476d6baef0c910831c7b3"/>
+  <int value="520"
+      label="c942262c0c7c0a95bb152b71c42556ddbe9a04fa8378373550d2b7ce27d952a3"/>
+  <int value="521"
+      label="42431627ea76cc78697f915e3455b1b2ec82ff2f6380ee6423ef3c0840b7e631"/>
+  <int value="522"
+      label="693c9aa6b245b3b0261637750863eadb6c248a16e52d6f4bc90c86bbf32d7042"/>
+  <int value="523"
+      label="a02fafa192c8cb81cb1341554f9c05b71cca2a890b0d1298d683647c961efbdf"/>
+  <int value="524"
+      label="e04a022ce32f4ccf2c7f6046287b828a32a909f5e751447f83fd2c71f6fd8173"/>
+  <int value="525"
+      label="ae7f962cb9e6a7dbf7b833fb18fa9b71a89175df949c232b6a9ef7cb3df2bbfc"/>
+  <int value="526"
+      label="96352d0ad875c027db82d599baa8d42e5c472649981eceed3bfc65f4c81fd5c1"/>
+  <int value="527"
+      label="e14e51891f3492243eea613bc2c814d47224b224c57d38169e958e30b3dedee4"/>
+  <int value="528"
+      label="b15ac9561204756124b9c4d3fe406d93833ff66652f67fbf139f5bbf030a0e64"/>
+  <int value="529"
+      label="a495c8d110e8b9e200f370aeda3ff92ee43f8e3d4ec0db1c0dc58bd762880ba5"/>
+  <int value="530"
+      label="d6ec6348a7c4d42ac48d9c43145a8cd71971362363267c6673a77b8a8573a66b"/>
+  <int value="531"
+      label="6a97b51c8219e93e5dec64bad5806cdeb0f8355be47e757010b702456e01aafd"/>
+  <int value="532"
+      label="48a8a7ecd03a83b26aec7574d09d6453e95f90360634ce204bcbd473997d4c05"/>
+  <int value="533"
+      label="c2b3c31a4a29850aa8f3cf472a1169ff71b416579f6a4482ec7744b83df988ac"/>
+  <int value="534"
+      label="fc784300ec8df4d3d1bad763835182918d52a9ff0238bdf695a1cd9bdb98321c"/>
+  <int value="535"
+      label="762195c225586ee6c0237456e2107dc54f1efc21f61a792ebd515913cce68332"/>
+  <int value="536"
+      label="681dc482c296c8402c6ebb20e68309a3bc846523ae34b984a84ee697a3312db7"/>
+  <int value="537"
+      label="f0011f92fcf9be36c7a5b36e7bc862ab20e94ef36fea8a561db0a8d7750c1f51"/>
+  <int value="538"
+      label="fee8af929175687f4638a3fc983db8ecd0e5e2a83e737f3fb77b4c22fcbac0a6"/>
+  <int value="539"
+      label="bdaccbf2e8b27c0c02a689ee866c9b86ec04442afcdddd5d4ec36def21e761dd"/>
+  <int value="540"
+      label="581cc15821169694c39c2991b53e93ab945a42b076661774c2ecf38a3323acea"/>
+  <int value="541"
+      label="bb0ce7040314a143dcd10e65ccaeef7010e1b784d15d195d77b5601956bf9e3f"/>
+  <int value="542"
+      label="de7b6932e9c44582ce0de07abdab7eea90c75d6d2a07331df57bd5cb88553d13"/>
+</enum>
+
+<enum name="NetworkConnectionCost">
+  <int value="0" label="Unknown"/>
+  <int value="1" label="Unmetered"/>
+  <int value="2" label="Metered"/>
+</enum>
+
+<enum name="NsswitchService">
+  <int value="0" label="Unknown"/>
+  <int value="1" label="&quot;files&quot;"/>
+  <int value="2" label="&quot;dns&quot;"/>
+  <int value="3" label="&quot;mdns&quot;"/>
+  <int value="4" label="&quot;mdns4&quot;"/>
+  <int value="5" label="&quot;mdns6&quot;"/>
+  <int value="6" label="&quot;mdns_minimal&quot;"/>
+  <int value="7" label="&quot;mdns4_minimal&quot;"/>
+  <int value="8" label="&quot;mdns6_minimal&quot;"/>
+  <int value="9" label="&quot;myhostname&quot;"/>
+  <int value="10" label="&quot;resolve&quot;"/>
+  <int value="11" label="&quot;nis&quot;"/>
+</enum>
+
+<enum name="OnTransferSizeUpdatedFrom">
+  <int value="0" label="CacheAliasSearchPrefetchURLLoader (Proxy)"/>
+  <int value="1" label="CorsURLLoader (Proxy)"/>
+  <int value="2" label="DelegatingURLLoaderClient (Proxy)"/>
+  <int value="3" label="DownloadResponseHandler (No-op)"/>
+  <int value="4" label="DriveFsURLLoaderClient (No-op)"/>
+  <int value="5" label="EmptyURLLoaderClient (No-op)"/>
+  <int value="6" label="FakeEmbeddedWorkerInstanceClient (No-op)"/>
+  <int value="7" label="HeaderRewritingURLLoaderClient (Proxy)"/>
+  <int value="8" label="InterceptedRequest (Proxy)"/>
+  <int value="9" label="InterceptionJob (Proxy+Work)"/>
+  <int value="10" label="MimeSniffingURLLoader (Proxy)"/>
+  <int value="11" label="MojoURLLoaderClient (Work)"/>
+  <int value="12" label="NavigationBodyLoader (Work)"/>
+  <int value="13" label="NavigationPreloadRequest (No-op)"/>
+  <int value="14" label="NavigationURLLoaderImpl (No-op)"/>
+  <int value="15" label="ObjectNavigationFallbackBodyLoader (No-op)"/>
+  <int value="16" label="PrefetchProxyProxyingURLLoaderFactory (Proxy)"/>
+  <int value="17" label="PrefetchURLLoader (Proxy)"/>
+  <int value="18" label="PreloadURLLoaderClient (No-op)"/>
+  <int value="19" label="ProxyingURLLoaderFactory (Proxy)"/>
+  <int value="20" label="ResultRecordingClient (Proxy)"/>
+  <int value="21" label="ServiceWorkerNewScriptFetcher (No-op)"/>
+  <int value="22" label="ServiceWorkerSingleScriptUpdateChecker (No-op)"/>
+  <int value="23" label="SignedExchangeCertFetcher (No-op)"/>
+  <int value="24" label="SignedExchangeLoader (No-op)"/>
+  <int value="25" label="SignedExchangePrefetchHandler (No-op)"/>
+  <int value="26" label="SimpleURLLoaderImpl (No-op)"/>
+  <int value="27" label="StreamingSearchPrefetchURLLoader (Proxy+Work)"/>
+  <int value="28" label="ThrottlingURLLoader (MaybeProxy)"/>
+  <int value="29" label="URLLoaderClientCheckedRemote (Proxy)"/>
+  <int value="30" label="URLLoaderRelay (Proxy)"/>
+  <int value="31" label="URLLoaderStatusMonitor"/>
+  <int value="32" label="WebBundleURLLoaderClient (Proxy)"/>
+  <int value="33" label="WebRequestProxyingURLLoaderFactory (Proxy)"/>
+  <int value="34" label="WorkerMainScriptLoader (No-op)"/>
+  <int value="35" label="WorkerScriptFetcher (No-op)"/>
+  <int value="36" label="WorkerScriptLoader (Proxy)"/>
+</enum>
+
+<enum name="PathValidationReason">
+  <int value="0" label="Reason unknown"/>
+  <int value="1" label="Multi port"/>
+  <int value="2" label="Reverse path validation"/>
+  <int value="3" label="Server preferred address migration"/>
+  <int value="4" label="Port migration"/>
+  <int value="5" label="Connection migration"/>
+</enum>
+
+<enum name="Ports">
+  <int value="80" label="Port 80"/>
+  <int value="443" label="Port 443"/>
+</enum>
+
+<enum name="ProxyScheme">
+  <int value="1" label="SCHEME_INVALID"/>
+  <int value="2" label="SCHEME_DIRECT"/>
+  <int value="4" label="SCHEME_HTTP"/>
+  <int value="8" label="SCHEME_SOCKS4"/>
+  <int value="16" label="SCHEME_SOCKS5"/>
+  <int value="32" label="SCHEME_HTTPS"/>
+  <int value="64" label="SCHEME_QUIC"/>
+</enum>
+
+<enum name="PushedStreamVaryResponseHeaderValues">
+  <int value="0" label="There is no Vary header."/>
+  <int value="1" label="The value of Vary is empty."/>
+  <int value="2" label="The value of Vary is &quot;*&quot;."/>
+  <int value="3"
+      label="The value of Vary is &quot;accept-encoding&quot; (case
+             insensitive)."/>
+  <int value="4"
+      label="The value of Vary contains &quot;accept-encoding&quot; (case
+             insensitive) and some other field names as well."/>
+  <int value="5"
+      label="The value of Vary does not contain &quot;accept-encoding&quot;,
+             is not empty, and is not &quot;*&quot;."/>
+</enum>
+
+<enum name="QuicAddressMismatch">
+  <int value="0" label="Address mismatch: IPv4 IPv4"/>
+  <int value="1" label="Address mismatch: IPv6 IPv6"/>
+  <int value="2" label="Address mismatch: IPv4 IPv6"/>
+  <int value="3" label="Address mismatch: IPv6 IPv4"/>
+  <int value="4" label="Port mismatch: IPv4 IPv4"/>
+  <int value="5" label="Port mismatch: IPv6 IPv6"/>
+  <int value="6" label="Address and port match: IPv4 IPv4"/>
+  <int value="7" label="Address and port match: IPv6 IPv6"/>
+</enum>
+
+<enum name="QuicAltSvcFormat">
+  <int value="0" label="Google format"/>
+  <int value="1" label="IETF format"/>
+</enum>
+
+<enum name="QuicBadPacketLossEvents">
+  <int value="1" label="ONE_PACKET_LOST"/>
+  <int value="2" label="TWO_PACKETS_LOST"/>
+  <int value="3" label="THREE_PACKETS_LOST"/>
+  <int value="4" label="FOUR_PACKETS_LOST"/>
+  <int value="5" label="FIVE_PACKETS_LOST"/>
+</enum>
+
+<enum name="QuicConnectionMigrationStatus">
+  <int value="0" label="No stream to migrate"/>
+  <int value="1" label="Already migrated"/>
+  <int value="2" label="Internal error"/>
+  <int value="3" label="Too many migrations"/>
+  <int value="4" label="Success"/>
+  <int value="5" label="Disabled by non-migratable stream"/>
+  <int value="6" label="Migration not enabled"/>
+  <int value="7" label="No alternate network"/>
+  <int value="8" label="Disabled by too many path degradings"/>
+  <int value="9" label="Disabled by config"/>
+  <int value="10" label="Path degrading not enabled"/>
+  <int value="11" label="Timeout with no new network"/>
+  <int value="12"
+      label="Exceeding maximum number of migrations on write error"/>
+  <int value="13" label="Path degrading before handshake confirmed"/>
+  <int value="14" label="Idle migration period exceeded"/>
+  <int value="15" label="Migration fails due to lack of connection ID"/>
+</enum>
+
+<enum name="QuicDisabledReason">
+  <int value="1" label="Public reset post handshake"/>
+  <int value="2" label="Timeout with open streams"/>
+  <int value="3" label="Bad packet loss rate"/>
+</enum>
+
+<enum name="QuicDiskCacheFailureReason">
+  <int value="0" label="WAIT_FOR_DATA_READY_INVALID_ARGUMENT_FAILURE"/>
+  <int value="1" label="GET_BACKEND_FAILURE"/>
+  <int value="2" label="OPEN_FAILURE"/>
+  <int value="3" label="CREATE_OR_OPEN_FAILURE"/>
+  <int value="4" label="PARSE_NO_DATA_FAILURE"/>
+  <int value="5" label="PARSE_FAILURE"/>
+  <int value="6" label="READ_FAILURE"/>
+  <int value="7" label="READY_TO_PERSIST_FAILURE"/>
+  <int value="8" label="PERSIST_NO_BACKEND_FAILURE"/>
+  <int value="9" label="WRITE_FAILURE"/>
+  <int value="10" label="NO_FAILURE"/>
+  <int value="11" label="PARSE_DATA_DECODE_FAILURE"/>
+</enum>
+
+<enum name="QuicDroppedPacketReason">
+  <int value="0" label="INVALID_PUBLIC_HEADER"/>
+  <int value="1" label="VERSION_MISMATCH"/>
+  <int value="2" label="INVALID_VERSION_NEGOTIATION_PACKET"/>
+  <int value="3" label="INVALID_PUBLIC_RESET_PACKET"/>
+  <int value="4" label="INVALID_PACKET_NUMBER"/>
+  <int value="5" label="INVALID_DIVERSIFICATION_NONCE"/>
+  <int value="6" label="DECRYPTION_FAILURE"/>
+</enum>
+
+<enum name="QuicErrorCodes">
+  <int value="0" label="NO_ERROR"/>
+  <int value="1" label="INTERNAL_ERROR"/>
+  <int value="2" label="STREAM_DATA_AFTER_TERMINATION"/>
+  <int value="3" label="INVALID_PACKET_HEADER"/>
+  <int value="4" label="INVALID_FRAME_DATA"/>
+  <int value="5" label="INVALID_FEC_DATA"/>
+  <int value="6" label="INVALID_RST_STREAM_DATA"/>
+  <int value="7" label="INVALID_CONNECTION_CLOSE_DATA"/>
+  <int value="8" label="INVALID_GOAWAY_DATA"/>
+  <int value="9" label="INVALID_ACK_DATA"/>
+  <int value="10" label="INVALID_VERSION_NEGOTIATION_PACKET"/>
+  <int value="11" label="INVALID_PUBLIC_RST_PACKET"/>
+  <int value="12" label="DECRYPTION_FAILURE"/>
+  <int value="13" label="ENCRYPTION_FAILURE"/>
+  <int value="14" label="PACKET_TOO_LARGE"/>
+  <int value="15" label="PACKET_FOR_NONEXISTENT_STREAM"/>
+  <int value="16" label="PEER_GOING_AWAY"/>
+  <int value="17" label="INVALID_STREAM_ID"/>
+  <int value="18" label="TOO_MANY_OPEN_STREAMS"/>
+  <int value="19" label="PUBLIC_RESET"/>
+  <int value="20" label="INVALID_VERSION"/>
+  <int value="21" label="STREAM_RST_BEFORE_HEADERS_DECOMPRESSED"/>
+  <int value="22" label="INVALID_HEADER_ID"/>
+  <int value="23" label="INVALID_NEGOTIATED_VALUE"/>
+  <int value="24" label="DECOMPRESSION_FAILURE"/>
+  <int value="25" label="NETWORK_IDLE_TIMEOUT"/>
+  <int value="26" label="ERROR_MIGRATING_ADDRESS"/>
+  <int value="27" label="PACKET_WRITE_ERROR"/>
+  <int value="28" label="HANDSHAKE_FAILED"/>
+  <int value="29" label="CRYPTO_TAGS_OUT_OF_ORDER"/>
+  <int value="30" label="CRYPTO_TOO_MANY_ENTRIES"/>
+  <int value="31" label="CRYPTO_INVALID_VALUE_LENGTH"/>
+  <int value="32" label="CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE"/>
+  <int value="33" label="INVALID_CRYPTO_MESSAGE_TYPE"/>
+  <int value="34" label="INVALID_CRYPTO_MESSAGE_PARAMETER"/>
+  <int value="35" label="CRYPTO_MESSAGE_PARAMETER_NOT_FOUND"/>
+  <int value="36" label="CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP"/>
+  <int value="37" label="CRYPTO_MESSAGE_INDEX_NOT_FOUND"/>
+  <int value="38" label="CRYPTO_INTERNAL_ERROR"/>
+  <int value="39" label="CRYPTO_VERSION_NOT_SUPPORTED"/>
+  <int value="40" label="CRYPTO_NO_SUPPORT"/>
+  <int value="41" label="CRYPTO_TOO_MANY_REJECTS"/>
+  <int value="42" label="PROOF_INVALID"/>
+  <int value="43" label="CRYPTO_DUPLICATE_TAG"/>
+  <int value="44" label="CRYPTO_ENCRYPTION_LEVEL_INCORRECT"/>
+  <int value="45" label="CRYPTO_SERVER_CONFIG_EXPIRED"/>
+  <int value="46" label="INVALID_STREAM_DATA"/>
+  <int value="47" label="INVALID_CONGESTION_FEEDBACK_DATA"/>
+  <int value="48" label="MISSING_PAYLOAD"/>
+  <int value="49" label="INVALID_PRIORITY"/>
+  <int value="50" label="EMPTY_STREAM_FRAME_NO_FIN"/>
+  <int value="51" label="PACKET_READ_ERROR"/>
+  <int value="52" label="INVALID_CHANNEL_ID_SIGNATURE"/>
+  <int value="53" label="CRYPTO_SYMMETRIC_KEY_SETUP_FAILED"/>
+  <int value="54" label="CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO"/>
+  <int value="55" label="VERSION_NEGOTIATION_MISMATCH"/>
+  <int value="56" label="INVALID_HEADERS_STREAM_DATA"/>
+  <int value="57" label="INVALID_WINDOW_UPDATE_DATA"/>
+  <int value="58" label="INVALID_BLOCKED_DATA"/>
+  <int value="59" label="FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA"/>
+  <int value="60" label="INVALID_STOP_WAITING_DATA"/>
+  <int value="61" label="UNENCRYPTED_STREAM_DATA"/>
+  <int value="62" label="CONNECTION_IP_POOLED"/>
+  <int value="63" label="FLOW_CONTROL_SENT_TOO_MUCH_DATA"/>
+  <int value="64" label="FLOW_CONTROL_INVALID_WINDOW"/>
+  <int value="65" label="CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE"/>
+  <int value="66" label="TOO_MANY_UNFINISHED_STREAMS"/>
+  <int value="67" label="HANDSHAKE_TIMEOUT"/>
+  <int value="68" label="TOO_MANY_OUTSTANDING_SENT_PACKETS"/>
+  <int value="69" label="TOO_MANY_OUTSTANDING_RECEIVED_PACKETS"/>
+  <int value="70" label="CONNECTION_CANCELLED"/>
+  <int value="71" label="BAD_PACKET_LOSS_RATE"/>
+  <int value="72" label="CRYPTO_HANDSHAKE_STATELESS_REJECT"/>
+  <int value="73" label="PUBLIC_RESETS_POST_HANDSHAKE"/>
+  <int value="74" label="TIMEOUTS_WITH_OPEN_STREAMS"/>
+  <int value="75" label="FAILED_TO_SERIALIZE_PACKET"/>
+  <int value="76" label="TOO_MANY_AVAILABLE_STREAMS"/>
+  <int value="77" label="UNENCRYPTED_FEC_DATA"/>
+  <int value="78" label="INVALID_PATH_CLOSE_DATA"/>
+  <int value="79" label="BAD_MULTIPATH_FLAG"/>
+  <int value="80" label="IP_ADDRESS_CHANGED"/>
+  <int value="81" label="CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS"/>
+  <int value="82" label="CONNECTION_MIGRATION_TOO_MANY_CHANGES"/>
+  <int value="83" label="CONNECTION_MIGRATION_NO_NEW_NETWORK"/>
+  <int value="84" label="CONNECTION_MIGRATION_NON_MIGRATABLE_STREAM"/>
+  <int value="85" label="TOO_MANY_RTOS"/>
+  <int value="86" label="ERROR_MIGRATING_PORT"/>
+  <int value="87" label="OVERLAPPING_STREAM_DATA"/>
+  <int value="88" label="ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA"/>
+  <int value="89" label="MAYBE_CORRUPTED_MEMORY"/>
+  <int value="90" label="CRYPTO_CHLO_TOO_LARGE"/>
+  <int value="91" label="MULTIPATH_PATH_DOES_NOT_EXIST"/>
+  <int value="92" label="MULTIPATH_PATH_NOT_ACTIVE"/>
+  <int value="93" label="TOO_MANY_STREAM_DATA_INTERVALS"/>
+  <int value="94" label="UNSUPPORTED_PROOF_DEMAND"/>
+  <int value="95" label="STREAM_SEQUENCER_INVALID_STATE"/>
+  <int value="96" label="TOO_MANY_SESSIONS_ON_SERVER"/>
+  <int value="97" label="HEADERS_STREAM_DATA_DECOMPRESS_FAILURE"/>
+  <int value="98" label="STREAM_LENGTH_OVERFLOW"/>
+  <int value="99" label="CONNECTION_MIGRATION_DISABLED_BY_CONFIG"/>
+  <int value="100" label="CONNECTION_MIGRATION_INTERNAL_ERROR"/>
+  <int value="101" label="INVALID_APPLICATION_CLOSE_DATA"/>
+  <int value="102" label="INVALID_MAX_DATA_FRAME_DATA"/>
+  <int value="103" label="INVALID_MAX_STREAM_DATA_FRAME_DATA"/>
+  <int value="104" label="MAX_STREAMS_DATA"/>
+  <int value="105" label="STREAMS_BLOCKED_DATA"/>
+  <int value="106" label="INVALID_STREAM_BLOCKED_DATA"/>
+  <int value="107" label="INVALID_NEW_CONNECTION_ID_DATA"/>
+  <int value="108" label="INVALID_STOP_SENDING_FRAME_DATA"/>
+  <int value="109" label="INVALID_PATH_CHALLENGE_DATA"/>
+  <int value="110" label="INVALID_PATH_RESPONSE_DATA"/>
+  <int value="111" label="CONNECTION_MIGRATION_HANDSHAKE_UNCONFIRMED"/>
+  <int value="112" label="INVALID_MESSAGE_DATA"/>
+  <int value="113" label="IETF_QUIC_PROTOCOL_VIOLATION"/>
+  <int value="114" label="INVALID_NEW_TOKEN"/>
+  <int value="115" label="DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM"/>
+  <int value="116" label="TRY_TO_WRITE_DATA_ON_READ_UNIDIRECTIONAL_STREAM"/>
+  <int value="117" label="INVALID_RETIRE_CONNECTION_ID_DATA"/>
+  <int value="118" label="STREAMS_BLOCKED_ERROR"/>
+  <int value="119" label="MAX_STREAMS_ERROR"/>
+  <int value="120" label="HTTP_DECODER_ERROR"/>
+  <int value="121" label="STALE_CONNECTION_CANCELLED"/>
+  <int value="122" label="IETF_GQUIC_ERROR_MISSING"/>
+  <int value="123"
+      label="WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM"/>
+  <int value="124" label="TOO_MANY_BUFFERED_CONTROL_FRAMES"/>
+  <int value="125" label="TRANSPORT_INVALID_CLIENT_INDICATION"/>
+  <int value="126" label="QPACK_DECOMPRESSION_FAILED"/>
+  <int value="127" label="QPACK_ENCODER_STREAM_ERROR"/>
+  <int value="128" label="QPACK_DECODER_STREAM_ERROR"/>
+  <int value="129" label="STREAM_DATA_BEYOND_CLOSE_OFFSET"/>
+  <int value="130" label="STREAM_MULTIPLE_OFFSET"/>
+  <int value="131" label="HTTP_FRAME_TOO_LARGE"/>
+  <int value="132" label="HTTP_FRAME_ERROR"/>
+  <int value="133" label="HTTP_FRAME_UNEXPECTED_ON_SPDY_STREAM"/>
+  <int value="134" label="HTTP_FRAME_UNEXPECTED_ON_CONTROL_STREAM"/>
+  <int value="135" label="HPACK_INDEX_VARINT_ERROR"/>
+  <int value="136" label="HPACK_NAME_LENGTH_VARINT_ERROR"/>
+  <int value="137" label="HPACK_VALUE_LENGTH_VARINT_ERROR"/>
+  <int value="138" label="HPACK_NAME_TOO_LONG"/>
+  <int value="139" label="HPACK_VALUE_TOO_LONG"/>
+  <int value="140" label="HPACK_NAME_HUFFMAN_ERROR"/>
+  <int value="141" label="HPACK_VALUE_HUFFMAN_ERROR"/>
+  <int value="142" label="HPACK_MISSING_DYNAMIC_TABLE_SIZE_UPDATE"/>
+  <int value="143" label="HPACK_INVALID_INDEX"/>
+  <int value="144" label="HPACK_INVALID_NAME_INDEX"/>
+  <int value="145" label="HPACK_DYNAMIC_TABLE_SIZE_UPDATE_NOT_ALLOWED"/>
+  <int value="146"
+      label="HPACK_INITIAL_TABLE_SIZE_UPDATE_IS_ABOVE_LOW_WATER_MARK"/>
+  <int value="147"
+      label="HPACK_TABLE_SIZE_UPDATE_IS_ABOVE_ACKNOWLEDGED_SETTING"/>
+  <int value="148" label="HPACK_TRUNCATED_BLOCK"/>
+  <int value="149" label="HPACK_FRAGMENT_TOO_LONG"/>
+  <int value="150" label="HPACK_COMPRESSED_HEADER_SIZE_EXCEEDS_LIMIT"/>
+  <int value="151" label="HTTP_INVALID_FRAME_SEQUENCE_ON_SPDY_STREAM"/>
+  <int value="152" label="HTTP_INVALID_FRAME_SEQUENCE_ON_CONTROL_STREAM"/>
+  <int value="153" label="HTTP_DUPLICATE_UNIDIRECTIONAL_STREAM"/>
+  <int value="154" label="HTTP_SERVER_INITIATED_BIDIRECTIONAL_STREAM"/>
+  <int value="155" label="HTTP_STREAM_WRONG_DIRECTION"/>
+  <int value="156" label="HTTP_CLOSED_CRITICAL_STREAM"/>
+  <int value="157" label="HTTP_MISSING_SETTINGS_FRAME"/>
+  <int value="158" label="HTTP_DUPLICATE_SETTING_IDENTIFIER"/>
+  <int value="159" label="HTTP_INVALID_MAX_PUSH_ID"/>
+  <int value="160" label="HTTP_STREAM_LIMIT_TOO_LOW"/>
+  <int value="161" label="ZERO_RTT_UNRETRANSMITTABLE"/>
+  <int value="162" label="ZERO_RTT_REJECTION_LIMIT_REDUCED"/>
+  <int value="163" label="ZERO_RTT_RESUMPTION_LIMIT_REDUCED"/>
+  <int value="164" label="HTTP_ZERO_RTT_RESUMPTION_SETTINGS_MISMATCH"/>
+  <int value="165" label="HTTP_ZERO_RTT_REJECTION_SETTINGS_MISMATCH"/>
+  <int value="166" label="HTTP_GOAWAY_INVALID_STREAM_ID"/>
+  <int value="167" label="HTTP_GOAWAY_ID_LARGER_THAN_PREVIOUS"/>
+  <int value="168" label="SILENT_IDLE_TIMEOUT"/>
+  <int value="169" label="QUIC_HTTP_RECEIVE_SPDY_SETTING"/>
+  <int value="170" label="QUIC_MISSING_WRITE_KEYS"/>
+  <int value="171" label="QUIC_HTTP_RECEIVE_SPDY_FRAME"/>
+  <int value="172" label="QUIC_KEY_UPDATE_ERROR"/>
+  <int value="173" label="QUIC_AEAD_LIMIT_REACHED"/>
+  <int value="174" label="QUIC_QPACK_ENCODER_STREAM_INTEGER_TOO_LARGE"/>
+  <int value="175" label="QUIC_QPACK_ENCODER_STREAM_STRING_LITERAL_TOO_LONG"/>
+  <int value="176" label="QUIC_QPACK_ENCODER_STREAM_HUFFMAN_ENCODING_ERROR"/>
+  <int value="177" label="QUIC_QPACK_ENCODER_STREAM_INVALID_STATIC_ENTRY"/>
+  <int value="178" label="QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_STATIC"/>
+  <int value="179"
+      label="QUIC_QPACK_ENCODER_STREAM_INSERTION_INVALID_RELATIVE_INDEX"/>
+  <int value="180"
+      label="QUIC_QPACK_ENCODER_STREAM_INSERTION_DYNAMIC_ENTRY_NOT_FOUND"/>
+  <int value="181" label="QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_DYNAMIC"/>
+  <int value="182" label="QUIC_QPACK_ENCODER_STREAM_ERROR_INSERTING_LITERAL"/>
+  <int value="183"
+      label="QUIC_QPACK_ENCODER_STREAM_DUPLICATE_INVALID_RELATIVE_INDEX"/>
+  <int value="184"
+      label="QUIC_QPACK_ENCODER_STREAM_DUPLICATE_DYNAMIC_ENTRY_NOT_FOUND"/>
+  <int value="185"
+      label="QUIC_QPACK_ENCODER_STREAM_SET_DYNAMIC_TABLE_CAPACITY"/>
+  <int value="186" label="QUIC_QPACK_DECODER_STREAM_INTEGER_TOO_LARGE"/>
+  <int value="187" label="QUIC_QPACK_DECODER_STREAM_INVALID_ZERO_INCREMENT"/>
+  <int value="188" label="QUIC_QPACK_DECODER_STREAM_INCREMENT_OVERFLOW"/>
+  <int value="189" label="QUIC_QPACK_DECODER_STREAM_IMPOSSIBLE_INSERT_COUNT"/>
+  <int value="190" label="QUIC_QPACK_DECODER_STREAM_INCORRECT_ACKNOWLEDGEMENT"/>
+  <int value="191" label="QUIC_MAX_AGE_TIMEOUT"/>
+  <int value="192" label="QUIC_INVALID_0RTT_PACKET_NUMBER_OUT_OF_ORDER"/>
+  <int value="193" label="QUIC_INVALID_PRIORITY_UPDATE"/>
+  <int value="194" label="QUIC_PEER_PORT_CHANGE_HANDSHAKE_UNCONFIRMED"/>
+  <int value="195" label="QUIC_TLS_BAD_CERTIFICATE"/>
+  <int value="196" label="QUIC_TLS_UNSUPPORTED_CERTIFICATE"/>
+  <int value="197" label="QUIC_TLS_CERTIFICATE_REVOKED"/>
+  <int value="198" label="QUIC_TLS_CERTIFICATE_EXPIRED"/>
+  <int value="199" label="QUIC_TLS_CERTIFICATE_UNKNOWN"/>
+  <int value="200" label="QUIC_TLS_INTERNAL_ERROR"/>
+  <int value="201" label="QUIC_TLS_UNRECOGNIZED_NAME"/>
+  <int value="202" label="QUIC_TLS_CERTIFICATE_REQUIRED"/>
+  <int value="203" label="QUIC_CONNECTION_ID_LIMIT_ERROR"/>
+  <int value="204" label="QUIC_TOO_MANY_CONNECTION_ID_WAITING_TO_RETIRE"/>
+  <int value="205" label="QUIC_HTTP_RECEIVE_SERVER_PUSH"/>
+  <int value="206" label="QUIC_INVALID_CHARACTER_IN_FIELD_VALUE"/>
+</enum>
+
+<enum name="QuicHandshakeFailureReason">
+  <int value="0" label="UNKNOWN"/>
+  <int value="1" label="BLACK_HOLE"/>
+  <int value="2" label="PUBLIC_RESET"/>
+</enum>
+
+<enum name="QuicHandshakeState">
+  <int value="0" label="STARTED"/>
+  <int value="1" label="ENCRYPTION_ESTABLISHED"/>
+  <int value="2" label="HANDSHAKE_CONFIRMED"/>
+  <int value="3" label="FAILED"/>
+</enum>
+
+<enum name="QuicHttp3ErrorCodes">
+  <int value="256" label="H3_NO_ERROR"/>
+  <int value="257" label="H3_GENERAL_PROTOCOL_ERROR"/>
+  <int value="258" label="H3_INTERNAL_ERROR"/>
+  <int value="259" label="H3_STREAM_CREATION_ERROR"/>
+  <int value="260" label="H3_CLOSED_CRITICAL_STREAM"/>
+  <int value="261" label="H3_FRAME_UNEXPECTED"/>
+  <int value="262" label="H3_FRAME_ERROR"/>
+  <int value="263" label="H3_EXCESSIVE_LOAD"/>
+  <int value="264" label="H3_ID_ERROR"/>
+  <int value="265" label="H3_SETTINGS_ERROR"/>
+  <int value="266" label="H3_MISSING_SETTINGS"/>
+  <int value="267" label="H3_REQUEST_REJECTED"/>
+  <int value="268" label="H3_REQUEST_CANCELLED"/>
+  <int value="269" label="H3_REQUEST_INCOMPLETE"/>
+  <int value="271" label="H3_CONNECT_ERROR"/>
+  <int value="272" label="H3_VERSION_FALLBACK"/>
+  <int value="512" label="QPACK_DECOMPRESSION_FAILED"/>
+  <int value="513" label="QPACK_ENCODER_STREAM_ERROR"/>
+  <int value="514" label="QPACK_DECODER_STREAM_ERROR"/>
+</enum>
+
+<enum name="QuicKeyUpdateReason">
+  <int value="0" label="kInvalid"/>
+  <int value="1" label="kRemote"/>
+  <int value="2" label="kLocalForTests"/>
+  <int value="3" label="kLocalForInteropRunner"/>
+  <int value="4" label="kLocalAeadConfidentialityLimit"/>
+  <int value="5" label="kLocalKeyUpdateLimitOverride"/>
+</enum>
+
+<enum name="QuicKeyUpdateSuccess">
+  <int value="0" label="kInvalid"/>
+  <int value="1" label="kSuccess"/>
+  <int value="2" label="kFailedInitial"/>
+  <int value="3" label="kFailedNonInitial"/>
+</enum>
+
+<enum name="QuicNotReusableReason">
+  <int value="0" label="NULLPTR"/>
+  <int value="1" label="TOO_SMALL"/>
+  <int value="2" label="REF_COUNT"/>
+</enum>
+
+<enum name="QuicPlatformNotification">
+  <int value="0" label="NETWORK_CONNECTED"/>
+  <int value="1" label="NETWORK_MADE_DEFAULT"/>
+  <int value="2" label="NETWORK_DISCONNECTED"/>
+  <int value="3" label="NETWORK_SOON_TO_DISCONNECT"/>
+  <int value="4" label="NETWORK_IP_ADDRESS_CHANGED"/>
+</enum>
+
+<enum name="QuicProtocolErrorRetryStatus">
+  <int value="0" label="NoRetryExceededMaxRetries"/>
+  <int value="1" label="NoRetryHeaderReceived"/>
+  <int value="2" label="NoRetryNoAlternativeService"/>
+  <int value="3" label="RetryAltServiceBroken"/>
+  <int value="4" label="RetryAltServiceNotBroken"/>
+</enum>
+
+<enum name="QuicRstStreamErrorCodes">
+  <int value="0" label="NO_ERROR"/>
+  <int value="1" label="ERROR_PROCESSING_STREAM"/>
+  <int value="2" label="MULTIPLE_TERMINATION_OFFSETS"/>
+  <int value="3" label="BAD_APPLICATION_PAYLOAD"/>
+  <int value="4" label="CONNECTION_ERROR"/>
+  <int value="5" label="PEER_GOING_AWAY"/>
+  <int value="6" label="CANCELLED"/>
+  <int value="7" label="RST_ACKNOWLEDGEMENT"/>
+  <int value="8" label="REFUSED"/>
+  <int value="9" label="INVALID_PROMISE_URL"/>
+  <int value="10" label="UNAUTHORIZED_PROMISE_URL"/>
+  <int value="11" label="DUPLICATE_PROMISE_URL"/>
+  <int value="12" label="PROMISE_VARY_MISMATCH"/>
+  <int value="13" label="INVALID_PROMISE_METHOD"/>
+  <int value="14" label="PUSH_STREAM_TIMED_OUT"/>
+  <int value="15" label="HEADERS_TOO_LARGE"/>
+  <int value="16" label="TTL_EXPIRED"/>
+  <int value="17" label="DATA_AFTER_CLOSE_OFFSET"/>
+  <int value="18" label="GENERAL_PROTOCOL_ERROR"/>
+  <int value="19" label="INTERNAL_ERROR"/>
+  <int value="20" label="CREATION_ERROR"/>
+  <int value="21" label="CLOSED_CRITICAL_STREAM"/>
+  <int value="22" label="FRAME_UNEXPECTED"/>
+  <int value="23" label="FRAME_ERROR"/>
+  <int value="24" label="EXCESSIVE_LOAD"/>
+  <int value="25" label="ID_ERROR"/>
+  <int value="26" label="SETTINGS_ERROR"/>
+  <int value="27" label="MISSING_SETTINGS"/>
+  <int value="28" label="REQUEST_REJECTED"/>
+  <int value="29" label="REQUEST_INCOMPLETE"/>
+  <int value="30" label="CONNECT_ERROR"/>
+  <int value="31" label="VERSION_FALLBACK"/>
+  <int value="32" label="DECOMPRESSION_FAILED"/>
+  <int value="33" label="ENCODER_STREAM_ERROR"/>
+  <int value="34" label="DECODER_STREAM_ERROR"/>
+  <int value="35" label="UNKNOWN_APPLICATION_ERROR_CODE"/>
+</enum>
+
+<enum name="QuicServerConfigState">
+  <int value="0" label="SERVER_CONFIG_EMPTY"/>
+  <int value="1" label="SERVER_CONFIG_INVALID"/>
+  <int value="2" label="SERVER_CONFIG_CORRUPTED"/>
+  <int value="3" label="SERVER_CONFIG_EXPIRED"/>
+  <int value="4" label="SERVER_CONFIG_INVALID_EXPIRY"/>
+  <int value="5" label="SERVER_CONFIG_VALID"/>
+</enum>
+
+<enum name="QuicSessionErrorCodes">
+  <int value="0" label="CONNECTING_SOCKET"/>
+  <int value="1" label="SETTING_RECEIVE_BUFFER"/>
+  <int value="2" label="SETTING_SEND_BUFFER"/>
+  <int value="3" label="SETTING_DO_NOT_FRAGMENT"/>
+</enum>
+
+<enum name="QuicTransportErrorCodes">
+  <int value="0" label="NO_ERROR"/>
+  <int value="1" label="INTERNAL_ERROR"/>
+  <int value="2" label="SERVER_BUSY"/>
+  <int value="3" label="FLOW_CONTROL_ERROR"/>
+  <int value="4" label="STREAM_LIMIT_ERROR"/>
+  <int value="5" label="STREAM_STATE_ERROR"/>
+  <int value="6" label="FINAL_SIZE_ERROR"/>
+  <int value="7" label="FRAME_ENCODING_ERROR"/>
+  <int value="8" label="TRANSPORT_PARAMETER_ERROR"/>
+  <int value="9" label="CONNECTION_ID_LIMIT_ERROR"/>
+  <int value="10" label="PROTOCOL_VIOLATION"/>
+  <int value="11" label="INVALID_TOKEN"/>
+  <int value="12" label="APPLICATION_ERROR"/>
+  <int value="13" label="CRYPTO_BUFFER_EXCEEDED"/>
+  <int value="14" label="KEY_UPDATE_ERROR"/>
+  <int value="256" label="CRYPTO_ERROR_close_notify"/>
+  <int value="266" label="CRYPTO_ERROR_unexpected_message"/>
+  <int value="276" label="CRYPTO_ERROR_bad_record_mac"/>
+  <int value="278" label="CRYPTO_ERROR_record_overflow"/>
+  <int value="296" label="CRYPTO_ERROR_handshake_failure"/>
+  <int value="298" label="CRYPTO_ERROR_bad_certificate"/>
+  <int value="299" label="CRYPTO_ERROR_unsupported_certificate"/>
+  <int value="300" label="CRYPTO_ERROR_certificate_revoked"/>
+  <int value="301" label="CRYPTO_ERROR_certificate_expired"/>
+  <int value="302" label="CRYPTO_ERROR_certificate_unknown"/>
+  <int value="303" label="CRYPTO_ERROR_illegal_parameter"/>
+  <int value="304" label="CRYPTO_ERROR_unknown_ca"/>
+  <int value="305" label="CRYPTO_ERROR_access_denied"/>
+  <int value="306" label="CRYPTO_ERROR_decode_error"/>
+  <int value="307" label="CRYPTO_ERROR_decrypt_error"/>
+  <int value="326" label="CRYPTO_ERROR_protocol_version"/>
+  <int value="327" label="CRYPTO_ERROR_insufficient_security"/>
+  <int value="336" label="CRYPTO_ERROR_internal_error"/>
+  <int value="342" label="CRYPTO_ERROR_inappropriate_fallback"/>
+  <int value="346" label="CRYPTO_ERROR_user_canceled"/>
+  <int value="365" label="CRYPTO_ERROR_missing_extension"/>
+  <int value="366" label="CRYPTO_ERROR_unsupported_extension"/>
+  <int value="368" label="CRYPTO_ERROR_unrecognized_name"/>
+  <int value="369" label="CRYPTO_ERROR_bad_certificate_status_response"/>
+  <int value="371" label="CRYPTO_ERROR_unknown_psk_identity"/>
+  <int value="372" label="CRYPTO_ERROR_certificate_required"/>
+  <int value="376" label="CRYPTO_ERROR_no_application_protocol"/>
+</enum>
+
+<enum name="QuicWriteStatus">
+  <int value="0" label="WRITE_STATUS_OK"/>
+  <int value="1" label="WRITE_STATUS_BLOCKED"/>
+  <int value="3" label="WRITE_STATUS_BLOCKED_DATA_BUFFERED"/>
+  <int value="4" label="WRITE_STATUS_ERROR"/>
+  <int value="5" label="WRITE_STATUS_MSG_TOO_BIG"/>
+  <int value="6" label="WRITE_STATUS_FAILED_TO_COALESCE_PACKET"/>
+</enum>
+
+<enum name="ResolutionCategory">
+  <int value="0" label="RESOLVE_SUCCESS"/>
+  <int value="1" label="RESOLVE_FAIL"/>
+  <int value="2" label="RESOLVE_SPECULATIVE_SUCCESS"/>
+  <int value="3" label="RESOLVE_SPECULATIVE_FAIL"/>
+  <int value="4" label="RESOLVE_ABORT"/>
+  <int value="5" label="RESOLVE_SPECULATIVE_ABORT"/>
+</enum>
+
+<enum name="RSAKeyUsage">
+  <int value="0" label="Not an RSA key"/>
+  <int value="1" label="OK (no extension)"/>
+  <int value="2" label="OK (both bits present)"/>
+  <int value="3" label="OK (digitalSignature present)"/>
+  <int value="4" label="OK (keyEncipherment present)"/>
+  <int value="5" label="Missing digitalSignature"/>
+  <int value="6" label="Missing keyEncipherment"/>
+  <int value="7" label="Error parsing certificate"/>
+</enum>
+
+<enum name="SCTOrigin">
+  <int value="0" label="SCT_EMBEDDED"/>
+  <int value="1" label="SCT_FROM_TLS_EXTENSION"/>
+  <int value="2" label="SCT_FROM_OCSP_RESPONSE"/>
+</enum>
+
+<enum name="SCTVerifyStatus">
+  <int value="0" label="SCT_STATUS_NONE"/>
+  <int value="1" label="SCT_STATUS_LOG_UNKNOWN"/>
+  <int value="2" label="DEPRECATED: SCT_STATUS_INVALID"/>
+  <int value="3" label="SCT_STATUS_OK"/>
+  <int value="4" label="SCT_STATUS_INVALID_SIGNATURE"/>
+  <int value="5" label="SCT_STATUS_INVALID_TIMESTAMP"/>
+</enum>
+
+<enum name="SecureDnsModeDetails">
+  <int value="0" label="Off, by user choice"/>
+  <int value="1" label="Off, by enterprise policy"/>
+  <int value="2" label="Off, due to managed environment"/>
+  <int value="3" label="Off, due to parental controls"/>
+  <int value="4" label="Automatic, by user choice"/>
+  <int value="5" label="Automatic, by enterprise policy"/>
+  <int value="6" label="Secure, by user choice"/>
+  <int value="7" label="Secure, by enterprise policy"/>
+</enum>
+
+<enum name="SharedDictionaryStoreError">
+  <int value="0" label="Ok"/>
+  <int value="1" label="FailedToInitializeDatabase"/>
+  <int value="2" label="InvalidSql"/>
+  <int value="3" label="FailedToExecuteSql"/>
+  <int value="4" label="FailedToBeginTransaction"/>
+  <int value="5" label="FailedToCommitTransaction"/>
+  <int value="6" label="InvalidTotalDictSize"/>
+  <int value="7" label="FailedToGetTotalDictSize"/>
+  <int value="8" label="FailedToSetTotalDictSize"/>
+  <int value="9" label="TooBigDictionary"/>
+</enum>
+
+<enum name="SpdyFrameFlowControlState">
+  <int value="0" label="Send not stalled"/>
+  <int value="1" label="Send stalled by stream"/>
+  <int value="2" label="Send stalled by session"/>
+  <int value="3" label="Send stalled by stream and session"/>
+</enum>
+
+<enum name="SpdyIPPoolDomainMatch">
+  <int value="0" label="mismatch"/>
+  <int value="1" label="match"/>
+</enum>
+
+<enum name="SpdyProtocolErrorDetails2">
+<!-- SpdyFramer::SpdyErrors -->
+
+  <int value="0" label="No error"/>
+  <int value="1" label="Invalid Control Frame"/>
+  <int value="2" label="Control Frame Payload Too Large"/>
+  <int value="3" label="Zlib Init Failure"/>
+  <int value="4" label="Unsupported Version"/>
+  <int value="5" label="Decompress Failure"/>
+  <int value="6" label="Compress Failure"/>
+  <int value="7" label="Credential Frame Corrupt"/>
+  <int value="8" label="Invalid Data Frame Flags"/>
+  <int value="9" label="Invalid Control Frame Flags"/>
+<!-- SpdyRstStreamStatus -->
+
+  <int value="10" label="(Unused)"/>
+  <int value="11" label="Protocol Error"/>
+  <int value="12" label="Closed Stream"/>
+  <int value="13" label="Refused Stream"/>
+  <int value="14" label="Unsupported Version (SpdyRstStreamStatus)"/>
+  <int value="15" label="Cancel"/>
+  <int value="16" label="Internal Error"/>
+  <int value="17" label="Flow Control Error"/>
+  <int value="18" label="Stream In Use"/>
+  <int value="19" label="Stream Already Closed"/>
+  <int value="20" label="Invalid Credentials"/>
+  <int value="21" label="Frame Too Large"/>
+<!-- SpdySession errors -->
+
+  <int value="22" label="Unexpected Ping"/>
+  <int value="23" label="Rst Stream For Non Active Stream"/>
+  <int value="24" label="Spdy Compression Failure"/>
+  <int value="25" label="Request For Secure Content Over Insecure Session"/>
+  <int value="26" label="Syn Reply Not Received"/>
+  <int value="27" label="Invalid Window Update Size"/>
+  <int value="28" label="Receive Window Size Violation"/>
+<!-- More SpdyFramer::SpdyErrors -->
+
+  <int value="29" label="GoAway Frame Corrupt"/>
+  <int value="30" label="RstStream Frame Corrupt"/>
+  <int value="31" label="Unexpected Frame (Expected Continuation)"/>
+<!-- More SpdyRstStreamStatus -->
+
+  <int value="32" label="Timeout waiting for settings acknowledgement"/>
+  <int value="33"
+      label="Connection established in response to CONNECT request was
+             abnormally closed"/>
+  <int value="34" label="Peer exhibiting suspect behavior."/>
+  <int value="35" label="Inadequate security."/>
+  <int value="36" label="HTTP/1.1 required."/>
+<!-- More SpdyFramer::SpdyErrors -->
+
+  <int value="37" label="Invalid control frame size."/>
+  <int value="38" label="Invalid stream ID."/>
+  <int value="39" label="Invalid padding length."/>
+  <int value="40" label="Oversized payload."/>
+<!-- More SpdyRstStreamStatus -->
+
+  <int value="41" label="No error."/>
+  <int value="42" label="Compression error."/>
+<!-- HttpDecoder or HttpDecoderAdapter errors -->
+
+  <int value="43" label="Varint beyond implementation limit."/>
+  <int value="44" label="Name length varint error."/>
+  <int value="45" label="Value legnth varint error."/>
+  <int value="46" label="Name string literal length exceeds buffer limit."/>
+  <int value="47" label="Value string literal length exceeds buffer limit."/>
+  <int value="48" label="Error in Huffman encoding for name."/>
+  <int value="49" label="Error in Huffman encoding for value."/>
+  <int value="50"
+      label="Next instruction should have been a dynamic table size update."/>
+  <int value="51"
+      label="Invalid index in indexed header field representation."/>
+  <int value="52"
+      label="Invalid index in literal header field with indexed name
+             representation."/>
+  <int value="53" label="Dynamic table size update not allowed."/>
+  <int value="54"
+      label="Initial dynamic table size update is above low water mark."/>
+  <int value="55"
+      label="Dynamic table size update is above acknowledged setting."/>
+  <int value="56" label="HPACK block ends in the middle of an instruction."/>
+  <int value="57" label="Incoming data fragment exceeds buffer limit."/>
+  <int value="58" label="Total compressed HPACK data size exceeds limit."/>
+</enum>
+
+<enum name="SpdyPushedStreamFate">
+  <int value="0" label="TOO_MANY_PUSHED_STREAMS"/>
+  <int value="1" label="TIMEOUT"/>
+  <int value="2" label="PROMISED_STREAM_ID_PARITY_ERROR"/>
+  <int value="3" label="ASSOCIATED_STREAM_ID_PARITY_ERROR"/>
+  <int value="4" label="STREAM_ID_OUT_OF_ORDER"/>
+  <int value="5" label="GOING_AWAY"/>
+  <int value="6" label="INVALID_URL"/>
+  <int value="7" label="INACTIVE_ASSOCIATED_STREAM"/>
+  <int value="8" label="NON_HTTP_SCHEME_FROM_TRUSTED_PROXY"/>
+  <int value="9" label="NON_HTTPS_PUSHED_SCHEME"/>
+  <int value="10" label="NON_HTTPS_ASSOCIATED_SCHEME"/>
+  <int value="11" label="CERTIFICATE_MISMATCH"/>
+  <int value="12" label="DUPLICATE_URL"/>
+  <int value="13" label="CLIENT_REQUEST_NOT_RANGE"/>
+  <int value="14" label="PUSHED_REQUEST_NOT_RANGE"/>
+  <int value="15" label="RANGE_MISMATCH"/>
+  <int value="16" label="VARY_MISMATCH"/>
+  <int value="17" label="ACCEPTED_NO_VARY"/>
+  <int value="18" label="ACCEPTED_MATCHING_VARY"/>
+  <int value="19" label="PUSH_DISABLED"/>
+  <int value="20" label="ALREADY_IN_CACHE"/>
+  <int value="21" label="UNSUPPORTED_STATUS_CODE"/>
+</enum>
+
+<enum name="SpdySessionGet">
+  <int value="0" label="created new"/>
+  <int value="1" label="found existing"/>
+  <int value="2" label="found existing from IP Pool"/>
+  <int value="3" label="imported from socket"/>
+</enum>
+
+<enum name="SSLECHResult">
+  <summary>The result of a TLS connection that offered ECH</summary>
+  <int value="0" label="The connection succeeded on the initial connection"/>
+  <int value="1"
+      label="The connection failed on the initial connection, without
+             providing retry configs"/>
+  <int value="2" label="The connection succeeded after getting retry configs"/>
+  <int value="3" label="The connection failed after getting retry configs"/>
+  <int value="4"
+      label="The connection succeeded after getting a rollback signal"/>
+  <int value="5" label="The connection failed after getting a rollback signal"/>
+</enum>
+
+<enum name="SSLHandshakeDetails">
+  <int value="0" label="TLS 1.2 (or earlier) full handshake (2-RTT)"/>
+  <int value="1" label="TLS 1.2 (or earlier) resumption (1-RTT)"/>
+  <int value="2" label="TLS 1.2 full handshake with False Start (1-RTT)"/>
+  <int value="3"
+      label="TLS 1.3 full handshake, HelloRetryRequest unknown (1-RTT or
+             2-RTT)"/>
+  <int value="4"
+      label="TLS 1.3 resumption handshake, HelloRetryRequest unknown (1-RTT
+             or 2-RTT)"/>
+  <int value="5" label="TLS 1.3 0-RTT handshake (0-RTT)"/>
+  <int value="6" label="TLS 1.3 full handshake (1-RTT)"/>
+  <int value="7" label="TLS 1.3 resumption handshake (1-RTT)"/>
+  <int value="8" label="TLS 1.3 full handshake with HelloRetryRequest (2-RTT)"/>
+  <int value="9"
+      label="TLS 1.3 resumption handshake with HelloRetryRequest (2-RTT)"/>
+</enum>
+
+<enum name="SSLHandshakeEarlyDataReason">
+<!-- Corresponds to //third_party/boringssl's ssl_early_data_reason_t -->
+
+  <int value="0"
+      label="The handshake has not progressed far enough for the 0-RTT status
+             to be known."/>
+  <int value="1" label="0-RTT is disabled for this connection."/>
+  <int value="2" label="0-RTT was accepted."/>
+  <int value="3"
+      label="The negotiated protocol version does not support 0-RTT."/>
+  <int value="4"
+      label="The peer declined to offer or accept 0-RTT for an unknown
+             reason."/>
+  <int value="5" label="The client did not offer a session."/>
+  <int value="6" label="The server declined to resume the session."/>
+  <int value="7" label="The session does not support 0-RTT."/>
+  <int value="8" label="The server sent a HelloRetryRequest."/>
+  <int value="9"
+      label="The negotiated ALPN protocol did not match the session."/>
+  <int value="10"
+      label="The connection negotiated Channel ID, which is incompatible with
+             0-RTT."/>
+  <int value="11"
+      label="The connection negotiated token binding, which is incompatible
+             with 0-RTT."/>
+  <int value="12" label="The client and server ticket age were too far apart."/>
+  <int value="13"
+      label="QUIC parameters differ between this connection and the original."/>
+</enum>
+
+<enum name="SSLKeyLogFileAction">
+  <int value="0" label="SSLKeyLogger enabled"/>
+  <int value="1" label="ssl-key-log-file switch set"/>
+  <int value="2" label="SSLKEYLOGFILE environment variable set"/>
+</enum>
+
+<enum name="SSLLegacyCryptoFallback">
+  <int value="0" label="No fallback used"/>
+  <int value="1" label="Used fallback and negotiated 3DES"/>
+  <int value="2" label="Used fallback and negotiated SHA-1"/>
+  <int value="3"
+      label="Used fallback and sent a certificate signed with
+             RSASSA-PKCS1-v1_5-SHA-1"/>
+  <int value="4"
+      label="Used fallback, negotiated 3DES, and sent a certificate signed
+             with RSASSA-PKCS1-v1_5-SHA-1"/>
+  <int value="5"
+      label="Used fallback, negotiated SHA-1, and sent a certificate signed
+             with RSASSA-PKCS1-v1_5-SHA-1"/>
+  <int value="6" label="Used fallback for unknown reason"/>
+</enum>
+
+<enum name="SSLNegotiatedAlpnProtocol">
+  <int value="0" label="ALPN not used"/>
+  <int value="1" label="HTTP/1.1 negotiated via ALPN"/>
+  <int value="2" label="HTTP/2 negotiated via ALPN"/>
+</enum>
+
+<enum name="SSLOrQUICVersion">
+  <int value="0" label="Unknown"/>
+  <int value="1" label="SSL 2.0"/>
+  <int value="2" label="SSL 3.0"/>
+  <int value="3" label="TLS 1.0"/>
+  <int value="4" label="TLS 1.1"/>
+  <int value="5" label="TLS 1.2"/>
+  <int value="6" label="TLS 1.3"/>
+  <int value="7" label="QUIC"/>
+</enum>
+
+<enum name="TPMSupport">
+  <int value="0" label="None"/>
+  <int value="1" label="RSA"/>
+  <int value="2" label="ECDSA"/>
+</enum>
+
+<enum name="TPMType">
+  <int value="0" label="None"/>
+  <int value="1" label="HW"/>
+  <int value="2" label="Virtual"/>
+  <int value="3" label="Both"/>
+</enum>
+
+<enum name="TrustTokenRequestHelperFactoryOutcome">
+  <int value="0" label="Successfully created an issuance helper"/>
+  <int value="1" label="Successfully created a redemption helper"/>
+  <int value="2" label="Successfully created a signing helper"/>
+  <int value="3" label="Empty 'issuers' parameter"/>
+  <int value="4" label="Unsuitable issuer in 'issuers' parameter"/>
+  <int value="5" label="Unsuitable top frame origin"/>
+  <int value="6"
+      label="Request rejected due to bearing an internal Trust Tokens header"/>
+  <int value="7" label="Rejected by authorizer (check cookie settings?)"/>
+</enum>
+
+<enum name="UnexportableKeyServiceResult">
+  <int value="0" label="Success"/>
+  <int value="1" label="Crypto API failed"/>
+  <int value="2" label="Key not found"/>
+  <int value="3" label="Key collision"/>
+  <int value="4" label="No key provider"/>
+  <int value="5" label="Algorithm not supported"/>
+  <int value="6" label="Key not ready"/>
+</enum>
+
+<enum name="UnsolicitedHttpsRecordStatus">
+  <int value="0" label="Malformed"/>
+  <int value="1" label="Alias"/>
+  <int value="2" label="Service"/>
+</enum>
+
+<enum name="URLRequestReferrerPolicy">
+  <int value="0" label="CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE"/>
+  <int value="1"
+      label="REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN"/>
+  <int value="2" label="ORIGIN_ONLY_ON_TRANSITION_CROSS_ORIGIN"/>
+  <int value="3" label="NEVER_CLEAR_REFERRER"/>
+  <int value="4" label="ORIGIN"/>
+  <int value="5" label="CLEAR_REFERRER_ON_TRANSITION_CROSS_ORIGIN"/>
+  <int value="6" label="ORIGIN_CLEAR_ON_TRANSITION_FROM_SECURE_TO_INSECURE"/>
+  <int value="7" label="NO_REFERRER"/>
+</enum>
+
+<enum name="WebSocketFallbackResult">
+  <int value="0" label="Success over HTTP/1.1"/>
+  <int value="1" label="Success over HTTP/2"/>
+  <int value="2" label="Success over HTTP/1.1 after fallback"/>
+  <int value="3" label="Failure without fallback"/>
+  <int value="4" label="Failure after fallback"/>
+</enum>
+
+<enum name="WebSocketHandshakeResult2">
+  <int value="0" label="INCOMPLETE">
+    Handshake not completed via Upgrade over HTTP/1 connection.
+  </int>
+  <int value="1" label="INVALID_STATUS">
+    Server responded to Upgrade request with invalid status.
+  </int>
+  <int value="2" label="EMPTY_RESPONSE">
+    Server responded to Upgrade request with empty response.
+  </int>
+  <int value="3" label="FAILED_SWITCHING_PROTOCOLS">
+    Server responded to Upgrade request with 101 status but there was some other
+    network error.
+  </int>
+  <int value="4" label="FAILED_UPGRADE">
+    Server responded to Upgrade request with invalid Upgrade header.
+  </int>
+  <int value="5" label="FAILED_ACCEPT">
+    Server responded to Upgrade request with invalid Sec-WebSocket-Accept
+    header.
+  </int>
+  <int value="6" label="FAILED_CONNECTION">
+    Server responded to Upgrade request with invalid Connection header.
+  </int>
+  <int value="7" label="FAILED_SUBPROTO">
+    Server responded to Upgrade request with invalid Sec-WebSocket-Protocol
+    header.
+  </int>
+  <int value="8" label="FAILED_EXTENSIONS">
+    Server responded to Upgrade request with invalid Sec-WebSocket-Extensions
+    header.
+  </int>
+  <int value="9" label="FAILED">
+    Upgrade request failed due to other network error.
+  </int>
+  <int value="10" label="CONNECTED">
+    Connected via Upgrade over HTTP/1 connection.
+  </int>
+  <int value="11" label="HTTP2_INCOMPLETE">
+    Handshake not completed over an HTTP/2 connection.
+  </int>
+  <int value="12" label="HTTP2_FAILED_STATUS">
+    Server responded to WebSocket request over an HTTP/2 connection with invalid
+    status code.
+  </int>
+  <int value="13" label="HTTP2_FAILED_SUBPROTO">
+    Server responded to WebSocket request over an HTTP/2 connection with invalid
+    sec-websocket-protocol header.
+  </int>
+  <int value="14" label="HTTP2_FAILED_EXTENSIONS">
+    Server responded to WebSocket request over an HTTP/2 connection with invalid
+    sec-websocket-extensions header.
+  </int>
+  <int value="15" label="HTTP2_FAILED">
+    WebSocket request over an HTTP/2 connection failed with some other error.
+  </int>
+  <int value="16" label="HTTP2_CONNECTED">
+    Connected over an HTTP/2 connection.
+  </int>
+  <int value="17" label="HTTP3_INCOMPLETE">
+    Handshake not completed over an HTTP/3 connection.
+  </int>
+  <int value="18" label="HTTP3_FAILED_STATUS">
+    Server responded to WebSocket request over an HTTP/3 connection with invalid
+    status code.
+  </int>
+  <int value="19" label="HTTP3_FAILED_SUBPROTO">
+    Server responded to WebSocket request over an HTTP/3 connection with invalid
+    sec-websocket-protocol header.
+  </int>
+  <int value="20" label="HTTP3_FAILED_EXTENSIONS">
+    Server responded to WebSocket request over an HTTP/3 connection with invalid
+    sec-websocket-extensions header.
+  </int>
+  <int value="21" label="HTTP3_FAILED">
+    WebSocket request over an HTTP/3 connection failed with some other error.
+  </int>
+  <int value="22" label="HTTP3_CONNECTED">
+    Connected over an HTTP/3 connection.
+  </int>
+</enum>
+
+<enum name="ZeroRttState">
+  <int value="0" label="Attempted and succeeded"/>
+  <int value="1" label="Attempted and rejected"/>
+  <int value="2" label="Not Attempted"/>
+</enum>
+
+<enum name="ZstdFilterDecodingStatus">
+  <int value="0" label="In progress"/>
+  <int value="1" label="End of Frame"/>
+  <int value="2" label="Error"/>
+</enum>
+
+<enum name="ZstdFilterErrorCode">
+  <int value="0" label="No error detected"/>
+  <int value="1" label="Error (generic)"/>
+  <int value="2" label="Reserved (2)"/>
+  <int value="3" label="Reserved (3)"/>
+  <int value="4" label="Reserved (4)"/>
+  <int value="5" label="Reserved (5)"/>
+  <int value="6" label="Reserved (6)"/>
+  <int value="7" label="Reserved (7)"/>
+  <int value="8" label="Reserved (8)"/>
+  <int value="9" label="Reserved (9)"/>
+  <int value="10" label="Unknown frame descriptor"/>
+  <int value="11" label="Reserved (11)"/>
+  <int value="12" label="Version not supported"/>
+  <int value="13" label="Reserved (13)"/>
+  <int value="14" label="Unsupported frame parameter"/>
+  <int value="15" label="Reserved (15)"/>
+  <int value="16" label="Frame requires too much memory for decoding"/>
+  <int value="17" label="Reserved (17)"/>
+  <int value="18" label="Reserved (18)"/>
+  <int value="19" label="Reserved (19)"/>
+  <int value="20" label="Data corruption detected"/>
+  <int value="21" label="Reserved (21)"/>
+  <int value="22" label="Restored data doesn't match checksum"/>
+  <int value="23" label="Reserved (23)"/>
+  <int value="24"
+      label="Header of Literals' block doesn't respect format specification"/>
+  <int value="25" label="Reserved (25)"/>
+  <int value="26" label="Reserved (26)"/>
+  <int value="27" label="Reserved (27)"/>
+  <int value="28" label="Reserved (28)"/>
+  <int value="29" label="Reserved (29)"/>
+  <int value="30" label="Dictionary is corrupted"/>
+  <int value="31" label="Reserved (31)"/>
+  <int value="32" label="Dictionary mismatch"/>
+  <int value="33" label="Reserved (33)"/>
+  <int value="34" label="Cannot create Dictionary from provided samples"/>
+  <int value="35" label="Reserved (35)"/>
+  <int value="36" label="Reserved (36)"/>
+  <int value="37" label="Reserved (37)"/>
+  <int value="38" label="Reserved (38)"/>
+  <int value="39" label="Reserved (39)"/>
+  <int value="40" label="Unsupported parameter"/>
+  <int value="41" label="Unsupported combination of parameters"/>
+  <int value="42" label="Parameter is out of bound"/>
+  <int value="43" label="Reserved (43)"/>
+  <int value="44" label="TableLog requires too much memory : unsupported"/>
+  <int value="45" label="Reserved (45)"/>
+  <int value="46" label="Unsupported max Symbol Value : too large"/>
+  <int value="47" label="Reserved (47)"/>
+  <int value="48" label="Specified maxSymbolValue is too small"/>
+  <int value="49" label="Reserved (49)"/>
+  <int value="50" label="Pledged buffer stability condition is not respected"/>
+  <int value="51" label="Reserved (51)"/>
+  <int value="52" label="Reserved (52)"/>
+  <int value="53" label="Reserved (53)"/>
+  <int value="54" label="Reserved (54)"/>
+  <int value="55" label="Reserved (55)"/>
+  <int value="56" label="Reserved (56)"/>
+  <int value="57" label="Reserved (57)"/>
+  <int value="58" label="Reserved (58)"/>
+  <int value="59" label="Reserved (59)"/>
+  <int value="60" label="Operation not authorized at current processing stage"/>
+  <int value="61" label="Reserved (61)"/>
+  <int value="62" label="Context should be init first"/>
+  <int value="63" label="Reserved (63)"/>
+  <int value="64" label="Allocation error : not enough memory"/>
+  <int value="65" label="Reserved (65)"/>
+  <int value="66" label="WorkSpace buffer is not large enough"/>
+  <int value="67" label="Reserved (67)"/>
+  <int value="68" label="Reserved (68)"/>
+  <int value="69" label="Reserved (69)"/>
+  <int value="70" label="Destination buffer is too small"/>
+  <int value="71" label="Reserved (71)"/>
+  <int value="72" label="Src size is incorrect"/>
+  <int value="73" label="Reserved (73)"/>
+  <int value="74" label="Operation on NULL destination buffer"/>
+  <int value="75" label="Reserved (75)"/>
+  <int value="76" label="Reserved (76)"/>
+  <int value="77" label="Reserved (77)"/>
+  <int value="78" label="Reserved (78)"/>
+  <int value="79" label="Reserved (79)"/>
+  <int value="80"
+      label="Operation made no progress over multiple calls, due to output
+             buffer being full"/>
+  <int value="81" label="Reserved (81)"/>
+  <int value="82"
+      label="Operation made no progress over multiple calls, due to input
+             being empty"/>
+  <int value="83" label="Reserved (83)"/>
+  <int value="84" label="Reserved (84)"/>
+  <int value="85" label="Reserved (85)"/>
+  <int value="86" label="Reserved (86)"/>
+  <int value="87" label="Reserved (87)"/>
+  <int value="88" label="Reserved (88)"/>
+  <int value="89" label="Reserved (89)"/>
+  <int value="90" label="Reserved (90)"/>
+  <int value="91" label="Reserved (91)"/>
+  <int value="92" label="Reserved (92)"/>
+  <int value="93" label="Reserved (93)"/>
+  <int value="94" label="Reserved (94)"/>
+  <int value="95" label="Reserved (95)"/>
+  <int value="96" label="Reserved (96)"/>
+  <int value="97" label="Reserved (97)"/>
+  <int value="98" label="Reserved (98)"/>
+  <int value="99" label="Reserved (99)"/>
+  <int value="100" label="Frame index is too large"/>
+  <int value="101" label="Reserved (101)"/>
+  <int value="102" label="An I/O error occurred when reading/seeking"/>
+  <int value="103" label="Reserved (103)"/>
+  <int value="104" label="Destination buffer is wrong"/>
+  <int value="105" label="Source buffer is wrong"/>
+  <int value="106"
+      label="Block-level external sequence producer returned an error code"/>
+  <int value="107" label="External sequences are not valid"/>
+  <int value="108" label="Reserved (108)"/>
+  <int value="109" label="Reserved (109)"/>
+  <int value="110" label="Reserved (110)"/>
+  <int value="111" label="Reserved (111)"/>
+  <int value="112" label="Reserved (112)"/>
+  <int value="113" label="Reserved (113)"/>
+  <int value="114" label="Reserved (114)"/>
+  <int value="115" label="Reserved (115)"/>
+  <int value="116" label="Reserved (116)"/>
+  <int value="117" label="Reserved (117)"/>
+  <int value="118" label="Reserved (118)"/>
+  <int value="119" label="Reserved (119)"/>
+</enum>
+
+</enums>
+
+</histogram-configuration>
diff --git a/tools/metrics/histograms/metadata/net/histograms.xml b/tools/metrics/histograms/metadata/net/histograms.xml
index 79e9d6b..2e70d84 100644
--- a/tools/metrics/histograms/metadata/net/histograms.xml
+++ b/tools/metrics/histograms/metadata/net/histograms.xml
@@ -70,7 +70,7 @@
 </variants>
 
 <histogram name="Crypto.TPMDuration.Virtual.{Operation}{SignatureAlgorithm}"
-    units="ms" expires_after="2024-03-01">
+    units="ms" expires_after="2024-05-05">
   <owner>kristianm@chromium.org</owner>
   <owner>agl@chromium.org</owner>
   <summary>
@@ -112,7 +112,7 @@
 </histogram>
 
 <histogram name="Crypto.TpmError.VirtualCreateKey" units="win32 error code"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>kristianm@chromium.org</owner>
   <owner>agl@chromium.org</owner>
   <summary>
@@ -122,7 +122,7 @@
 </histogram>
 
 <histogram name="Crypto.TpmError.VirtualFinalizeKey" units="win32 error code"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>kristianm@chromium.org</owner>
   <owner>agl@chromium.org</owner>
   <summary>
@@ -132,7 +132,7 @@
 </histogram>
 
 <histogram name="Crypto.TpmError.VirtualOpenKey" units="win32 error code"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>kristianm@chromium.org</owner>
   <owner>agl@chromium.org</owner>
   <summary>
@@ -142,7 +142,7 @@
 </histogram>
 
 <histogram name="Crypto.TpmError.VirtualOpenStorage" units="win32 error code"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>kristianm@chromium.org</owner>
   <owner>agl@chromium.org</owner>
   <summary>
@@ -196,7 +196,7 @@
 </histogram>
 
 <histogram name="Crypto.TPMSupport2" enum="TPMSupport"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>agl@chromium.org</owner>
   <owner>davidben@chromium.org</owner>
   <owner>wfh@chromium.org</owner>
@@ -207,7 +207,7 @@
 </histogram>
 
 <histogram name="Crypto.TPMSupportType" enum="TPMType"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>kristianm@chromium.org</owner>
   <owner>agl@chromium.org</owner>
   <summary>
@@ -322,7 +322,7 @@
 </histogram>
 
 <histogram name="Crypto.VirtualKeySupport" enum="TPMSupport"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>kristianm@chromium.org</owner>
   <owner>agl@chromium.org</owner>
   <summary>
@@ -2274,7 +2274,7 @@
 </histogram>
 
 <histogram name="Net.NetworkTransaction{HostType}.RetryReason"
-    enum="HttpNetworkTransactionRetryReason" expires_after="2024-03-01">
+    enum="HttpNetworkTransactionRetryReason" expires_after="2024-05-05">
   <owner>horo@chromium.org</owner>
   <owner>src/net/OWNERS</owner>
   <summary>Log the reason when HttpNetworkTransaction retries.</summary>
@@ -2668,7 +2668,7 @@
 </histogram>
 
 <histogram name="Net.QuicMultiPort.AltPortFailureWhenPathDegradingVsGeneral"
-    units="%" expires_after="2024-03-03">
+    units="%" expires_after="2024-05-05">
   <owner>renjietang@chromium.org</owner>
   <owner>src/net/quic/OWNERS</owner>
   <summary>
@@ -2678,7 +2678,7 @@
 </histogram>
 
 <histogram name="Net.QuicMultiPort.AltPortRttWhenPathDegradingVsGeneral"
-    units="%" expires_after="2024-03-03">
+    units="%" expires_after="2024-05-05">
   <owner>renjietang@chromium.org</owner>
   <owner>src/net/quic/OWNERS</owner>
   <summary>
@@ -2732,7 +2732,7 @@
 </histogram>
 
 <histogram name="Net.QuicNetworkDegradingDurationTillDisconnected" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>dschinazi@chromium.org</owner>
   <owner>src/net/quic/OWNERS</owner>
   <summary>
@@ -2769,7 +2769,7 @@
 </histogram>
 
 <histogram name="Net.QuicProtocolErrorRetryDelay{HostType}.{FinalResult}"
-    units="ms" expires_after="2024-03-01">
+    units="ms" expires_after="2024-05-05">
   <owner>horo@chromium.org</owner>
   <owner>src/net/OWNERS</owner>
   <summary>
@@ -2787,7 +2787,7 @@
 </histogram>
 
 <histogram name="Net.QuicProtocolError{HostType}.RetryStatus"
-    enum="QuicProtocolErrorRetryStatus" expires_after="2024-03-01">
+    enum="QuicProtocolErrorRetryStatus" expires_after="2024-05-05">
   <owner>horo@chromium.org</owner>
   <owner>src/net/OWNERS</owner>
   <summary>
@@ -2801,7 +2801,7 @@
 </histogram>
 
 <histogram name="Net.QuicProtocolError{HostType}.{RetryStatus}.QuicErrorCode"
-    enum="QuicErrorCodes" expires_after="2024-03-01">
+    enum="QuicErrorCodes" expires_after="2024-05-05">
   <owner>horo@chromium.org</owner>
   <owner>src/net/OWNERS</owner>
   <summary>
@@ -2823,7 +2823,7 @@
 
 <histogram
     name="Net.QuicProtocolError{HostType}.{RetryStatus}.QuicStreamErrorCode"
-    enum="QuicRstStreamErrorCodes" expires_after="2024-03-01">
+    enum="QuicRstStreamErrorCodes" expires_after="2024-05-05">
   <owner>horo@chromium.org</owner>
   <owner>src/net/OWNERS</owner>
   <summary>
@@ -3704,7 +3704,7 @@
 </histogram>
 
 <histogram name="Net.QuicSession.NumDefaultPathDegrading" units="times"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>renjietang@chromium.org</owner>
   <owner>src/net/quic/OWNERS</owner>
   <summary>
@@ -4785,7 +4785,7 @@
 </histogram>
 
 <histogram name="Net.RestrictedCookieManager.CookiePartitionKeyOK"
-    enum="Boolean" expires_after="2024-03-03">
+    enum="Boolean" expires_after="2024-05-05">
   <owner>dylancutler@google.com</owner>
   <owner>src/net/cookies/OWNERS</owner>
   <summary>
@@ -4855,7 +4855,7 @@
 </histogram>
 
 <histogram name="Net.RestrictedCookieManager.GetCookiesString.Count30Seconds"
-    units="IPCs" expires_after="2024-03-03">
+    units="IPCs" expires_after="2024-05-05">
   <owner>carlscab@google.com</owner>
   <owner>olivierli@chromium.org</owner>
   <owner>woa-performance@google.com</owner>
@@ -4869,7 +4869,7 @@
 </histogram>
 
 <histogram name="Net.RestrictedCookieManager.PartitionedCookiesInScript"
-    units="cookies" expires_after="2024-03-03">
+    units="cookies" expires_after="2024-05-05">
   <owner>dylancutler@google.com</owner>
   <owner>src/net/cookies/OWNERS</owner>
   <summary>
@@ -4954,7 +4954,7 @@
 
 <histogram
     name="Net.SharedDictionaryManagerOnDisk.TotalDictionaryCountWhenAdded"
-    units="count" expires_after="2024-03-03">
+    units="count" expires_after="2024-05-05">
   <owner>horo@chromium.org</owner>
   <owner>src/net/extras/shared_dictionary/OWNERS</owner>
   <summary>
@@ -4966,7 +4966,7 @@
 
 <histogram
     name="Net.SharedDictionaryManagerOnDisk.TotalDictionarySizeKBWhenAdded"
-    units="KB" expires_after="2024-03-03">
+    units="KB" expires_after="2024-05-05">
   <owner>horo@chromium.org</owner>
   <owner>src/net/extras/shared_dictionary/OWNERS</owner>
   <summary>
@@ -4978,7 +4978,7 @@
 
 <histogram
     name="Net.SharedDictionaryOnDisk.OpenEntryLatency.{SuccessOrFailure}"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>horo@chromium.org</owner>
   <owner>src/net/extras/shared_dictionary/OWNERS</owner>
   <summary>
@@ -4989,7 +4989,7 @@
 </histogram>
 
 <histogram name="Net.SharedDictionaryOnDisk.ReadDataLatency.{SuccessOrFailure}"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>horo@chromium.org</owner>
   <owner>src/net/extras/shared_dictionary/OWNERS</owner>
   <summary>
@@ -5036,7 +5036,7 @@
 </histogram>
 
 <histogram name="Net.SharedDictionaryStore.DictionarySizeKBPerSiteWhenAdded"
-    units="KB" expires_after="2024-03-03">
+    units="KB" expires_after="2024-05-05">
   <owner>horo@chromium.org</owner>
   <owner>src/net/extras/shared_dictionary/OWNERS</owner>
   <summary>
@@ -5073,7 +5073,7 @@
 
 <histogram
     name="Net.SharedDictionaryTransaction.DictionaryReadLatency.{SuccessOrFailure}"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>horo@chromium.org</owner>
   <owner>src/net/extras/shared_dictionary/OWNERS</owner>
   <summary>
@@ -5251,7 +5251,7 @@
 </histogram>
 
 <histogram name="Net.SpdySession.OnSettings.{StreamState}StreamCount"
-    units="count" expires_after="2024-01-24">
+    units="count" expires_after="2024-05-05">
   <owner>bashi@chromium.org</owner>
   <owner>chrome-network-stack@google.com</owner>
   <summary>
@@ -5989,7 +5989,7 @@
 </histogram>
 
 <histogram name="Net.ZstdFilter.MaxMemoryUsage" units="KB"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>nidhijaju@chromium.org</owner>
   <owner>blink-network-stack@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/network/histograms.xml b/tools/metrics/histograms/metadata/network/histograms.xml
index 58dd395..788c80df 100644
--- a/tools/metrics/histograms/metadata/network/histograms.xml
+++ b/tools/metrics/histograms/metadata/network/histograms.xml
@@ -650,7 +650,7 @@
 </histogram>
 
 <histogram name="Network.Ash.VPN.{VPNProviderType}.ConfigurationSource"
-    enum="VPNConfigurationSource" expires_after="2024-03-03">
+    enum="VPNConfigurationSource" expires_after="2024-05-05">
   <owner>chadduffin@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>
@@ -667,7 +667,7 @@
 </histogram>
 
 <histogram name="Network.Ash.WiFi.Hidden.RemovalAttempt"
-    units="network removal attempts" expires_after="2024-03-03">
+    units="network removal attempts" expires_after="2024-05-05">
   <owner>chadduffin@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>
@@ -679,7 +679,7 @@
 </histogram>
 
 <histogram name="Network.Ash.WiFi.Hidden.RemovalAttempt.Result"
-    enum="BooleanSuccess" expires_after="2024-03-03">
+    enum="BooleanSuccess" expires_after="2024-05-05">
   <owner>chadduffin@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>
@@ -694,7 +694,7 @@
 </histogram>
 
 <histogram name="Network.Ash.WiFi.Hidden.{LoginStatus}" enum="Boolean"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>chadduffin@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>
@@ -712,7 +712,7 @@
 </histogram>
 
 <histogram name="Network.Ash.{NetworkType}.ConnectionResult.All"
-    enum="ShillConnectResult" expires_after="2024-03-03">
+    enum="ShillConnectResult" expires_after="2024-05-05">
   <owner>hsuregan@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>
@@ -738,7 +738,7 @@
 </histogram>
 
 <histogram name="Network.Ash.{NetworkType}.ConnectionResult.UserInitiated"
-    enum="UserInitiatedNetworkConnectResult" expires_after="2024-03-03">
+    enum="UserInitiatedNetworkConnectResult" expires_after="2024-05-05">
   <owner>hsuregan@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>
@@ -749,7 +749,7 @@
 </histogram>
 
 <histogram name="Network.Ash.{NetworkType}.DisconnectionsWithoutUserAction"
-    enum="NetworkConnectionState" expires_after="2024-03-03">
+    enum="NetworkConnectionState" expires_after="2024-05-05">
   <owner>hsuregan@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>
@@ -772,7 +772,7 @@
 </histogram>
 
 <histogram name="Network.Ash.{TechnologyType}.EnabledState.{Operation}.Result"
-    enum="BooleanSuccess" expires_after="2024-03-03">
+    enum="BooleanSuccess" expires_after="2024-05-05">
   <owner>hsuregan@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>
@@ -793,7 +793,7 @@
 
 <histogram
     name="Network.Ash.{TechnologyType}.EnabledState.{Operation}.ResultCode"
-    enum="ShillConnectResult" expires_after="2024-03-03">
+    enum="ShillConnectResult" expires_after="2024-05-05">
   <owner>nikhilcn@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>
@@ -1285,7 +1285,7 @@
 </histogram>
 
 <histogram name="Network.Cellular.ESim.RequestPendingProfiles.Latency"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>nikhilcn@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>
@@ -1385,7 +1385,7 @@
 </histogram>
 
 <histogram name="Network.Cellular.ESim.Usage.Count" enum="NetworkCellularUsage"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>azeemarshad@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>
@@ -1767,7 +1767,7 @@
 </histogram>
 
 <histogram name="Network.DnsProxy.PlainTextProbe.{Family}.Results"
-    enum="DnsProxy.QueryResult" expires_after="2024-03-03">
+    enum="DnsProxy.QueryResult" expires_after="2024-05-05">
   <owner>jasongustaman@chromium.org</owner>
   <owner>cros-network-metrics@google.com</owner>
   <summary>
@@ -1798,7 +1798,7 @@
 </histogram>
 
 <histogram name="Network.DnsProxy.PlainTextProbe.{Family}.RetriesUntilSuccess"
-    units="count" expires_after="2024-03-03">
+    units="count" expires_after="2024-05-05">
   <owner>jasongustaman@chromium.org</owner>
   <owner>cros-network-metrics@google.com</owner>
   <summary>
@@ -1885,7 +1885,7 @@
 </histogram>
 
 <histogram name="Network.DnsProxy.{Family}Nameservers" units="units"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>garrick@chromium.org</owner>
   <owner>cros-network-metrics@google.com</owner>
   <summary>
@@ -1900,7 +1900,7 @@
 </histogram>
 
 <histogram name="Network.DnsProxy.{ProcessType}.Event"
-    enum="DnsProxy.ProcessEvent" expires_after="2024-03-03">
+    enum="DnsProxy.ProcessEvent" expires_after="2024-05-05">
   <owner>garrick@chromium.org</owner>
   <owner>cros-network-metrics@google.com</owner>
   <summary>
@@ -1918,7 +1918,7 @@
 </histogram>
 
 <histogram name="Network.DnsProxy.{Type}Query.Errors"
-    enum="DnsProxy.QueryError" expires_after="2024-03-03">
+    enum="DnsProxy.QueryError" expires_after="2024-05-05">
   <owner>garrick@chromium.org</owner>
   <owner>cros-network-metrics@google.com</owner>
   <summary>
@@ -1933,7 +1933,7 @@
 </histogram>
 
 <histogram name="Network.DnsProxy.{Type}Query.FailedResolveDuration" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>garrick@chromium.org</owner>
   <owner>cros-network-metrics@google.com</owner>
   <summary>
@@ -1954,7 +1954,7 @@
 </histogram>
 
 <histogram name="Network.DnsProxy.{Type}Query.ResolveDuration" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>garrick@chromium.org</owner>
   <owner>cros-network-metrics@google.com</owner>
   <summary>
@@ -1975,7 +1975,7 @@
 </histogram>
 
 <histogram name="Network.DnsProxy.{Type}Query.Results"
-    enum="DnsProxy.QueryResult" expires_after="2024-03-03">
+    enum="DnsProxy.QueryResult" expires_after="2024-05-05">
   <owner>garrick@chromium.org</owner>
   <owner>cros-network-metrics@google.com</owner>
   <summary>
@@ -2034,7 +2034,7 @@
 </histogram>
 
 <histogram name="Network.Multicast.ARC.ActiveTime" units="%"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>chuweih@google.com</owner>
   <owner>cros-network-metrics@google.com</owner>
   <summary>
@@ -2046,7 +2046,7 @@
 </histogram>
 
 <histogram name="Network.Multicast.ARC.WiFi.{Protocol}.ActiveCount"
-    units="packets" expires_after="2024-03-03">
+    units="packets" expires_after="2024-05-05">
   <owner>jasongustaman@chromium.org</owner>
   <owner>cros-network-metrics@google.com</owner>
   <summary>
@@ -2078,7 +2078,7 @@
 </histogram>
 
 <histogram name="Network.Multicast.TotalCount" units="packets"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jasongustaman@chromium.org</owner>
   <owner>cros-network-metrics@google.com</owner>
   <summary>
@@ -2089,7 +2089,7 @@
 </histogram>
 
 <histogram name="Network.Multicast.{Technology}.ConnectedCount" units="packets"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jasongustaman@chromium.org</owner>
   <owner>cros-network-metrics@google.com</owner>
   <summary>
@@ -2106,7 +2106,7 @@
 </histogram>
 
 <histogram name="Network.Multicast.{Technology}.{Protocol}.ConnectedCount"
-    units="packets" expires_after="2024-03-03">
+    units="packets" expires_after="2024-05-05">
   <owner>jasongustaman@chromium.org</owner>
   <owner>cros-network-metrics@google.com</owner>
   <summary>
@@ -2334,7 +2334,7 @@
 </histogram>
 
 <histogram name="Network.Shill.Cellular.ConnectResult.{ApnType}"
-    enum="PlatformCellularConnectResult" expires_after="2024-03-03">
+    enum="PlatformCellularConnectResult" expires_after="2024-05-05">
   <owner>danielwinkler@google.com</owner>
   <owner>cros-network-metrics@google.com</owner>
   <summary>
@@ -2560,7 +2560,7 @@
 </histogram>
 
 <histogram name="Network.Shill.Ethernet.Driver" enum="EthernetDriver"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>chuweih@google.com</owner>
   <owner>cros-network-metrics@google.com</owner>
   <summary>
@@ -3002,7 +3002,7 @@
 </histogram>
 
 <histogram name="Network.Shill.Vpn.OpenVPNCipher" enum="VPNOpenVPNCipher"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>taoyl@google.com</owner>
   <owner>cros-network-metrics@google.com</owner>
   <summary>
@@ -3161,7 +3161,7 @@
 </histogram>
 
 <histogram name="Network.Shill.Vpn.{VPNType}.IPType" enum="NetworkIPType"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jiejiang@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <owner>cros-network-metrics@google.com</owner>
@@ -3236,7 +3236,7 @@
 </histogram>
 
 <histogram name="Network.Shill.WiFi.ApAlternateEDCASupport"
-    enum="WiFiApAlternateEDCASupport" expires_after="2024-03-03">
+    enum="WiFiApAlternateEDCASupport" expires_after="2024-05-05">
   <owner>damiendejean@chromium.org</owner>
   <owner>cros-network-metrics@google.com</owner>
   <summary>
@@ -3277,7 +3277,7 @@
 </histogram>
 
 <histogram name="Network.Shill.WiFi.ApSCSupport" enum="WiFiApSCSupport"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>damiendejean@chromium.org</owner>
   <owner>cros-network-metrics@google.com</owner>
   <summary>
@@ -4200,7 +4200,7 @@
 </histogram>
 
 <histogram name="Network.Shill.{Technology}.IPType" enum="NetworkIPType"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jiejiang@chromium.org</owner>
   <owner>cros-connectivity@google.com</owner>
   <owner>cros-network-metrics@google.com</owner>
@@ -4463,7 +4463,7 @@
 </histogram>
 
 <histogram name="NetworkService.IpProtection.OAuthTokenFetchTime" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>djmitche@chromium.org</owner>
   <owner>src/chrome/browser/ip_protection/OWNERS</owner>
   <summary>
@@ -4483,7 +4483,7 @@
 </histogram>
 
 <histogram name="NetworkService.IpProtection.TokenExpirationRate"
-    units="tokens" expires_after="2024-03-03">
+    units="tokens" expires_after="2024-05-05">
   <owner>djmitche@chromium.org</owner>
   <owner>src/chrome/browser/ip_protection/OWNERS</owner>
   <summary>
@@ -4493,7 +4493,7 @@
 </histogram>
 
 <histogram name="NetworkService.IpProtection.TokenSpendRate" units="tokens"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>djmitche@chromium.org</owner>
   <owner>src/chrome/browser/ip_protection/OWNERS</owner>
   <summary>
@@ -4503,7 +4503,7 @@
 </histogram>
 
 <histogram name="NetworkService.IpProtection.TryGetAuthTokensResult"
-    enum="IpProtectionTokenBatchRequestResult" expires_after="2024-03-03">
+    enum="IpProtectionTokenBatchRequestResult" expires_after="2024-05-05">
   <owner>djmitche@chromium.org</owner>
   <owner>src/chrome/browser/ip_protection/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 2807b65..5bddae0 100644
--- a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
+++ b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
@@ -101,7 +101,7 @@
 </histogram>
 
 <histogram name="NewTabPage.BackgroundService.Images.Headers.ErrorDetected"
-    enum="NTPImageType" expires_after="2024-03-03">
+    enum="NTPImageType" expires_after="2024-05-05">
   <owner>pauladedeji@google.com</owner>
   <owner>danpeng@google.com</owner>
   <owner>chrome-desktop-ntp@google.com</owner>
@@ -114,7 +114,7 @@
 </histogram>
 
 <histogram name="NewTabPage.BackgroundService.Images.Headers.RequestLatency"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>danpeng@google.com</owner>
   <owner>pauladedeji@google.com</owner>
   <owner>chrome-desktop-ntp@google.com</owner>
@@ -127,7 +127,7 @@
 </histogram>
 
 <histogram name="NewTabPage.BackgroundService.Images.Headers.StatusCode"
-    units="HttpResponseCode" expires_after="2024-03-03">
+    units="HttpResponseCode" expires_after="2024-05-05">
   <owner>danpeng@google.com</owner>
   <owner>pauladedeji@google.com</owner>
   <owner>chrome-desktop-ntp@google.com</owner>
@@ -543,7 +543,7 @@
 </histogram>
 
 <histogram name="NewTabPage.CustomizeShortcutAction"
-    enum="NTPCustomizeShortcutAction" expires_after="2024-03-03">
+    enum="NTPCustomizeShortcutAction" expires_after="2024-05-05">
   <owner>tiborg@chromium.org</owner>
   <owner>yyushkina@chromium.org</owner>
   <owner>chrome-desktop-ntp@google.com</owner>
@@ -703,7 +703,7 @@
 </histogram>
 
 <histogram name="NewTabPage.HistoryClusters.HasDiscount" enum="Boolean"
-    expires_after="2024-02-11">
+    expires_after="2024-05-05">
   <owner>yuezhanggg@chromium.org</owner>
   <owner>chrome-shopping@google.com</owner>
   <owner>chrome-desktop-ntp@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/oobe/histograms.xml b/tools/metrics/histograms/metadata/oobe/histograms.xml
index 6c47b44..7ff2fff5 100644
--- a/tools/metrics/histograms/metadata/oobe/histograms.xml
+++ b/tools/metrics/histograms/metadata/oobe/histograms.xml
@@ -385,7 +385,7 @@
 </histogram>
 
 <histogram name="OOBE.BootToOOBECompleted.{CompletedOobeFlowType}" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>osamafathy@chromium.org</owner>
   <owner>cros-oobe@google.com</owner>
   <summary>
@@ -400,7 +400,7 @@
 </histogram>
 
 <histogram name="OOBE.BootToSignInCompleted" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>alemate@chromium.org</owner>
   <owner>rsorokin@chromium.org</owner>
   <owner>cros-oac@google.com</owner>
@@ -463,7 +463,7 @@
 </histogram>
 
 <histogram name="OOBE.ConsolidatedConsentScreen.RecoveryOptInResult"
-    enum="RecoveryOptInResult" expires_after="2024-03-03">
+    enum="RecoveryOptInResult" expires_after="2024-05-05">
   <owner>anastasiian@chromium.org</owner>
   <owner>cros-lurs@google.com</owner>
   <owner>cros-oobe@google.com</owner>
@@ -474,7 +474,7 @@
 </histogram>
 
 <histogram name="OOBE.ConsolidatedConsentScreen.UserActions"
-    enum="ConsolidatedConsentScreenUserAction" expires_after="2024-03-03">
+    enum="ConsolidatedConsentScreenUserAction" expires_after="2024-05-05">
   <owner>osamafathy@google.com</owner>
   <owner>cros-oobe@google.com</owner>
   <summary>
@@ -484,7 +484,7 @@
 </histogram>
 
 <histogram name="OOBE.ConsumerUpdateScreen.IsMandatory" enum="Boolean"
-    expires_after="2023-12-31">
+    expires_after="2024-05-05">
   <owner>osamafathy@google.com</owner>
   <owner>cros-oobe@google.com</owner>
   <summary>
@@ -496,7 +496,7 @@
 </histogram>
 
 <histogram name="OOBE.ConsumerUpdateScreen.IsOptionalUpdateSkipped"
-    enum="Boolean" expires_after="2023-12-31">
+    enum="Boolean" expires_after="2024-05-05">
   <owner>osamafathy@google.com</owner>
   <owner>cros-oobe@google.com</owner>
   <summary>
@@ -506,7 +506,7 @@
 </histogram>
 
 <histogram name="OOBE.ConsumerUpdateScreen.SkipReason"
-    enum="OobeConsumerUpdateScreenSkippedReason" expires_after="2023-12-31">
+    enum="OobeConsumerUpdateScreenSkippedReason" expires_after="2024-05-05">
   <owner>osamafathy@google.com</owner>
   <owner>cros-oobe@google.com</owner>
   <summary>
@@ -538,7 +538,7 @@
 </histogram>
 
 <histogram name="OOBE.Enrollment.IsUserEnrollingAConsumer" enum="Boolean"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>osamafathy@google.com</owner>
   <owner>cros-oobe@google.com</owner>
   <summary>
@@ -563,7 +563,7 @@
 </histogram>
 
 <histogram name="OOBE.FingerprintSetupScreen.UserActions"
-    enum="FingerprintSetupScreenUserAction" expires_after="2024-03-03">
+    enum="FingerprintSetupScreenUserAction" expires_after="2024-05-05">
   <owner>dkuzmin@google.com</owner>
   <owner>cros-oac@google.com</owner>
   <summary>
@@ -572,7 +572,7 @@
   </summary>
 </histogram>
 
-<histogram name="OOBE.GaiaLoginTime" units="ms" expires_after="2024-03-03">
+<histogram name="OOBE.GaiaLoginTime" units="ms" expires_after="2024-05-05">
   <owner>dkuzmin@google.com</owner>
   <owner>cros-oac@google.com</owner>
   <summary>
@@ -583,7 +583,7 @@
 </histogram>
 
 <histogram name="OOBE.GaiaPasswordChangedScreen.UserActions"
-    enum="GaiaPasswordChangedScreenUserAction" expires_after="2024-03-03">
+    enum="GaiaPasswordChangedScreenUserAction" expires_after="2024-05-05">
   <owner>dkuzmin@google.com</owner>
   <owner>cros-oac@google.com</owner>
   <summary>
@@ -593,7 +593,7 @@
 </histogram>
 
 <histogram name="OOBE.GaiaScreen.LoginRequests" enum="GaiaLoginVariant"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>dkuzmin@google.com</owner>
   <owner>rsorokin@google.com</owner>
   <owner>cros-oobe@google.com</owner>
@@ -608,7 +608,7 @@
 </histogram>
 
 <histogram name="OOBE.GaiaScreen.PasswordIgnoredChars" enum="Boolean"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>anastasiian@chromium.org</owner>
   <owner>cros-lurs@google.com</owner>
   <summary>
@@ -618,7 +618,7 @@
 </histogram>
 
 <histogram name="OOBE.GaiaScreen.SuccessLoginRequests" enum="GaiaLoginVariant"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>dkuzmin@google.com</owner>
   <owner>rsorokin@google.com</owner>
   <owner>cros-oobe@google.com</owner>
@@ -874,7 +874,7 @@
 </histogram>
 
 <histogram name="OOBE.RecommendApps.Screen.Action"
-    enum="RecommendAppsScreenAction" expires_after="2024-03-03">
+    enum="RecommendAppsScreenAction" expires_after="2024-05-05">
   <owner>dkuzmin@google.com</owner>
   <owner>cros-oac@google.com</owner>
   <owner>chromesky-eng@google.com</owner>
@@ -882,7 +882,7 @@
 </histogram>
 
 <histogram name="OOBE.RecommendApps.Screen.SelectedAppCount" units="apps"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>dkuzmin@google.com</owner>
   <owner>cros-oac@google.com</owner>
   <owner>chromesky-eng@google.com</owner>
@@ -898,7 +898,7 @@
 </histogram>
 
 <histogram name="OOBE.RecommendApps.Screen.State"
-    enum="RecommendAppsScreenState" expires_after="2024-03-03">
+    enum="RecommendAppsScreenState" expires_after="2024-05-05">
   <owner>dkuzmin@google.com</owner>
   <owner>cros-oac@google.com</owner>
   <owner>chromesky-eng@google.com</owner>
@@ -950,7 +950,7 @@
 </histogram>
 
 <histogram name="OOBE.StepShownStatus.Multidevice-setup-screen.Skipped"
-    enum="OobeMultideviceScreenSkippedReason" expires_after="2024-03-03">
+    enum="OobeMultideviceScreenSkippedReason" expires_after="2024-05-05">
   <owner>bhartmire@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -1006,7 +1006,7 @@
 </histogram>
 
 <histogram name="OOBE.SyncConsentScreen.Behavior" enum="SyncConsentBehavior"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>osamafathy@google.com</owner>
   <owner>cros-oac@google.com</owner>
   <summary>
@@ -1028,7 +1028,7 @@
 </histogram>
 
 <histogram name="OOBE.SyncConsentScreen.IsMinorUser" enum="Boolean"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>osamafathy@google.com</owner>
   <owner>cros-oac@google.com</owner>
   <summary>
@@ -1065,7 +1065,7 @@
 </histogram>
 
 <histogram name="OOBE.SyncConsentScreen.LoadingTime" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>osamafathy@google.com</owner>
   <owner>cros-oac@google.com</owner>
   <summary>
@@ -1075,7 +1075,7 @@
 </histogram>
 
 <histogram name="OOBE.SyncConsentScreen.ReviewFollowingSetup"
-    enum="BooleanChecked" expires_after="2024-03-03">
+    enum="BooleanChecked" expires_after="2024-05-05">
   <owner>dkuzmin@google.com</owner>
   <owner>cros-oac@google.com</owner>
   <summary>
@@ -1085,7 +1085,7 @@
 </histogram>
 
 <histogram name="OOBE.SyncConsentScreen.SyncEnabled" enum="BooleanEnabled"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>osamafathy@google.com</owner>
   <owner>cros-oac@google.com</owner>
   <summary>
@@ -1096,7 +1096,7 @@
 </histogram>
 
 <histogram name="OOBE.SyncConsentScreen.UserChoice"
-    enum="SyncConsentUserChoice" expires_after="2024-03-03">
+    enum="SyncConsentUserChoice" expires_after="2024-05-05">
   <owner>osamafathy@google.com</owner>
   <owner>cros-oac@google.com</owner>
   <summary>
@@ -1138,7 +1138,7 @@
 </histogram>
 
 <histogram name="OOBE.WebUI.LoadTime.FirstRun" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>rsorokin@chromium.org</owner>
   <owner>cros-oac@google.com</owner>
   <summary>
@@ -1169,7 +1169,7 @@
 </histogram>
 
 <histogram name="OOBE.WelcomeScreen.A11yUserActions"
-    enum="WelcomeScreenA11yUserAction" expires_after="2024-03-03">
+    enum="WelcomeScreenA11yUserAction" expires_after="2024-05-05">
   <owner>dkuzmin@google.com</owner>
   <owner>cros-oac@google.com</owner>
   <summary>
@@ -1180,7 +1180,7 @@
 </histogram>
 
 <histogram name="OOBE.WelcomeScreen.AcceptChromeVoxHint" enum="BooleanEnabled"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>akihiroota@google.com</owner>
   <owner>cros-oac@google.com</owner>
   <summary>
@@ -1190,7 +1190,7 @@
 </histogram>
 
 <histogram name="OOBE.WelcomeScreen.ChromeVoxHintSpokenSuccess"
-    enum="BooleanEnabled" expires_after="2024-03-03">
+    enum="BooleanEnabled" expires_after="2024-05-05">
   <owner>akihiroota@google.com</owner>
   <owner>cros-oac@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml
index ffcea29f..1002ea9 100644
--- a/tools/metrics/histograms/metadata/others/histograms.xml
+++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -227,7 +227,7 @@
 </histogram>
 
 <histogram name="AccessCodeCast.Session.FreezeDuration" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>bzielinski@google.com</owner>
   <owner>cros-edu-eng@google.com</owner>
   <summary>
@@ -238,7 +238,7 @@
 </histogram>
 
 <histogram name="AccessCodeCast.Session.NewDeviceRouteCreationDuration"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>bzielinski@google.com</owner>
   <owner>cros-edu-eng@google.com</owner>
   <summary>
@@ -342,7 +342,7 @@
 </histogram>
 
 <histogram name="AccessCodeCast.Ui.DialogOpenLocation"
-    enum="AccessCodeCastDialogOpenLocation" expires_after="2024-01-28">
+    enum="AccessCodeCastDialogOpenLocation" expires_after="2024-05-05">
   <owner>bzielinski@google.com</owner>
   <owner>cros-edu-eng@google.com</owner>
   <summary>
@@ -830,7 +830,7 @@
 </histogram>
 
 <histogram name="Ads.InterestGroup.BaDataConstructionTime" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>behamilton@google.com</owner>
   <owner>pauljensen@chromium.org</owner>
   <owner>privacy-sandbox-dev@chromium.org</owner>
@@ -847,7 +847,7 @@
 </histogram>
 
 <histogram name="Ads.InterestGroup.BaDataSize" units="bytes"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>behamilton@google.com</owner>
   <owner>pauljensen@chromium.org</owner>
   <owner>privacy-sandbox-dev@chromium.org</owner>
@@ -1227,53 +1227,6 @@
   </summary>
 </histogram>
 
-<histogram name="BlueZ.AdvertisementMonitor.NumOfMonitors" units="count"
-    expires_after="2023-12-11">
-  <owner>apusaka@chromium.org</owner>
-  <owner>chromeos-bt-platform-sw-core@google.com</owner>
-  <summary>
-    This is specific to Chrome OS. Records the number of active advertisement
-    monitors every couple of minutes. This helps us to gauge the additional
-    power requirement for the advertisement monitor feature.
-  </summary>
-</histogram>
-
-<histogram name="BlueZ.AdvertisementMonitor.{Filter}.FilterPatternsPerMinute"
-    units="count" expires_after="2023-12-11">
-  <owner>apusaka@chromium.org</owner>
-  <owner>chromeos-bt-platform-sw-core@google.com</owner>
-  <summary>
-    This is specific to Chrome OS. Records the number of advertisement packet
-    received in the user space while the advertisement monitor is done using
-    {Filter} filtering. This helps us to gauge the additional power requirement
-    for the advertisement monitor feature.
-  </summary>
-  <token key="Filter">
-    <variant name="MSFT"/>
-    <variant name="SW"/>
-  </token>
-</histogram>
-
-<histogram name="BlueZ.AdvertisementMonitor.{Filter}.{Operation}.Result"
-    enum="BlueZResultOfAdvertisementMonitor" expires_after="2023-12-11">
-  <owner>apusaka@chromium.org</owner>
-  <owner>chromeos-bt-platform-sw-core@google.com</owner>
-  <summary>
-    This is specific to Chrome OS. Records the outcome of {Operation} operation
-    of advertisement monitor when {Filter} filtering is used. This helps us to
-    verify the correctness of this feature as well as to point out possible
-    regression.
-  </summary>
-  <token key="Filter">
-    <variant name="MSFT"/>
-    <variant name="SW"/>
-  </token>
-  <token key="Operation">
-    <variant name="Add"/>
-    <variant name="Remove"/>
-  </token>
-</histogram>
-
 <histogram name="BlueZ.ChipLost2" units="seconds" expires_after="2024-04-28">
   <owner>sonnysasaka@chromium.org</owner>
   <owner>chromeos-bt-platform-sw-core@google.com</owner>
@@ -1841,7 +1794,7 @@
 </histogram>
 
 <histogram name="ChromiumAndroidLinker.RelroProvidedSuccessfully"
-    enum="BooleanSuccess" expires_after="2024-03-03">
+    enum="BooleanSuccess" expires_after="2024-05-05">
   <owner>lizeb@chromium.org</owner>
   <owner>pasko@chromium.org</owner>
   <summary>
@@ -1960,7 +1913,7 @@
 </histogram>
 
 <histogram name="ClientHints.AcceptCHFrame" enum="AcceptCHFrameRestart"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>victortan@chromium.org</owner>
   <owner>miketaylr@chromium.org</owner>
   <summary>
@@ -1972,7 +1925,7 @@
 </histogram>
 
 <histogram name="ClientHints.CriticalCHRestart" enum="CriticalCHRestart"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>victortan@chromium.org</owner>
   <owner>miketaylr@chromium.org</owner>
   <summary>
@@ -2000,7 +1953,7 @@
 </histogram>
 
 <histogram name="ClientHints.StoreLatency" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>miketaylr@chromium.org</owner>
   <owner>potassium-katabolism@google.com</owner>
   <summary>
@@ -2020,7 +1973,7 @@
 </histogram>
 
 <histogram name="ClientHints.UpdateSize" units="count"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>victortan@chromium.org</owner>
   <owner>potassium-katabolism@google.com</owner>
   <summary>
@@ -2553,7 +2506,7 @@
 </histogram>
 
 <histogram name="Conversions.CorruptReportsInDatabase2"
-    enum="ConversionCorruptReportStatus" expires_after="M121">
+    enum="ConversionCorruptReportStatus" expires_after="2024-05-05">
   <owner>tquintanilla@chromium.org</owner>
   <owner>apaseltiner@chromium.org</owner>
   <owner>measurement-api-dev+metrics@google.com</owner>
@@ -4567,7 +4520,7 @@
 </histogram>
 
 <histogram name="Feedback.ChromeOSApp.GetFeedbackLogsV2.DBusResult"
-    enum="GetFeedbackLogsV2DbusResult" expires_after="2024-03-03">
+    enum="GetFeedbackLogsV2DbusResult" expires_after="2024-05-05">
   <owner>xiangdongkong@google.com</owner>
   <owner>cros-feedback-app@google.com</owner>
   <summary>
@@ -4824,7 +4777,7 @@
 </histogram>
 
 <histogram name="Feedback.RedactionTool" enum="PIIType"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>nikj@google.com</owner>
   <owner>dpchromeos-core-eng@google.com</owner>
   <summary>
@@ -4849,7 +4802,7 @@
 </histogram>
 
 <histogram name="Feedback.RedactionTool.TimeSpentRedacting" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>cschlosser@chromium.org</owner>
   <owner>dpchromeos-core-eng@google.com</owner>
   <summary>
@@ -4861,7 +4814,7 @@
 </histogram>
 
 <histogram name="Feedback.RedactionTool.TimeSpentRedactingCrash" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>cschlosser@chromium.org</owner>
   <owner>dpchromeos-core-eng@google.com</owner>
   <summary>
@@ -6202,14 +6155,14 @@
 </histogram>
 
 <histogram name="Linux.SystemTheme.Default" enum="Ui.SystemTheme"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>thomasanderson@chromium.org</owner>
   <owner>thestig@chromium.org</owner>
   <summary>The default system theme. Logged once on startup.</summary>
 </histogram>
 
 <histogram name="Linux.SystemTheme.Profile" enum="Ui.SystemTheme"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>thomasanderson@chromium.org</owner>
   <owner>thestig@chromium.org</owner>
   <summary>
@@ -6271,7 +6224,7 @@
 
 <histogram name="LoadingPredictor.OptimizationHintsReceiveStatus"
     enum="LoadingPredictorOptimizationHintsReceiveStatus"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>sophiechang@chromium.org</owner>
   <owner>tbansal@chromium.org</owner>
   <owner>spelchat@chromium.org</owner>
@@ -6426,7 +6379,7 @@
 </histogram>
 
 <histogram name="Mac.LaunchApplicationResult" enum="MacLaunchApplicationResult"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>mek@chromium.org</owner>
   <owner>src/base/mac/OWNERS</owner>
   <summary>
@@ -6447,7 +6400,7 @@
 </histogram>
 
 <histogram name="Manifest.ParseIdResult" enum="ManifestParseIdResultType"
-    expires_after="2024-02-04">
+    expires_after="2024-05-05">
   <owner>phillis@chromium.org</owner>
   <owner>desktop-pwas-team@chromium.org</owner>
   <summary>Tracks the result of parsing id field in the Manifest.</summary>
@@ -6815,7 +6768,7 @@
 </histogram>
 
 <histogram name="OAuth2Login.SessionRestoreTimeToSuccess" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>anastasiian@chromium.org</owner>
   <owner>sinhak@chromium.org</owner>
   <summary>
@@ -7461,7 +7414,7 @@
 </histogram>
 
 <histogram name="PaintHolding.InputTiming4" enum="PaintHoldingInputTiming"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>pdr@chromium.org</owner>
   <owner>paint-dev@chromium.org</owner>
   <summary>
@@ -9638,7 +9591,7 @@
 </histogram>
 
 <histogram name="SubresourceWebBundles.LoadResult"
-    enum="SubresourceWebBundleLoadResult" expires_after="2024-03-01">
+    enum="SubresourceWebBundleLoadResult" expires_after="2024-05-05">
   <owner>horo@chromium.org</owner>
   <owner>webpackage-dev@chromium.org</owner>
   <summary>The result of loading subresource web bundles.</summary>
@@ -11078,7 +11031,7 @@
 </histogram>
 
 <histogram name="WebFont.CacheHit" enum="WebFontCacheHit"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hajimehoshi@chromium.org</owner>
   <owner>kenjibaheux@chromium.org</owner>
   <owner>kouhei@chromium.org</owner>
@@ -11612,10 +11565,12 @@
     <variant name="ShowChromeLabs"/>
     <variant name="ShowDownloads"/>
     <variant name="ShowHistory"/>
+    <variant name="ShowHistoryClustersSidePanel"/>
     <variant name="ShowKaleidoscope"/>
     <variant name="ShowPasswordManager"/>
     <variant name="ShowPaymentMethods"/>
     <variant name="ShowPerformanceSettings"/>
+    <variant name="ShowReadingModeSidePanel"/>
     <variant name="ShowSearchCompanion"/>
     <variant name="ShowSigninWhenPaused"/>
     <variant name="ShowSyncSettings"/>
diff --git a/tools/metrics/histograms/metadata/page/histograms.xml b/tools/metrics/histograms/metadata/page/histograms.xml
index 0bc55e1..3c6ef523 100644
--- a/tools/metrics/histograms/metadata/page/histograms.xml
+++ b/tools/metrics/histograms/metadata/page/histograms.xml
@@ -116,7 +116,7 @@
 </histogram>
 
 <histogram name="PageActionController.Icon.CTR2" enum="PageActionCTREvent"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>emshack@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
   <summary>
@@ -132,7 +132,7 @@
 </histogram>
 
 <histogram name="PageActionController.Icon.NumberActionsShownWhenClicked"
-    units="actions" expires_after="2024-03-01">
+    units="actions" expires_after="2024-05-05">
   <owner>emshack@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
   <summary>
@@ -142,7 +142,7 @@
 </histogram>
 
 <histogram name="PageActionController.NumberActionsShown2" units="actions"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>emshack@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
   <summary>
@@ -153,7 +153,7 @@
 </histogram>
 
 <histogram name="PageActionController.PagesWithActionsShown2"
-    enum="PageActionPageEvent" expires_after="2024-03-01">
+    enum="PageActionPageEvent" expires_after="2024-05-05">
   <owner>emshack@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
   <summary>
@@ -172,7 +172,7 @@
 </histogram>
 
 <histogram name="PageActionController.{PageActionType}.Icon.CTR2"
-    enum="PageActionCTREvent" expires_after="2024-03-01">
+    enum="PageActionCTREvent" expires_after="2024-05-05">
   <owner>emshack@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
   <summary>
@@ -727,7 +727,7 @@
 
 <histogram
     name="PageLoad.Clients.FromGoogleSearch.FromSidePanel.LayoutInstability.MaxCumulativeShiftScore.SessionWindow.Gap1000ms.Max5000ms2"
-    units="scorex10000" expires_after="2024-03-03">
+    units="scorex10000" expires_after="2024-05-05">
   <owner>tluk@chromium.org</owner>
   <owner>chrome-cros@chromium.org</owner>
   <summary>
@@ -1384,7 +1384,7 @@
 </histogram>
 
 <histogram name="PageLoad.Clients.{Origin}.FirstContentfulPaint" units="ms"
-    expires_after="2024-02-29">
+    expires_after="2024-05-05">
   <owner>chikamune@chromium.org</owner>
   <owner>loading-dev@chromium.org</owner>
   <summary>
@@ -1398,7 +1398,7 @@
 </histogram>
 
 <histogram name="PageLoad.Clients.{Origin}.InteractiveTiming.FirstInputDelay"
-    units="ms" expires_after="2024-02-29">
+    units="ms" expires_after="2024-05-05">
   <owner>chikamune@chromium.org</owner>
   <owner>loading-dev@chromium.org</owner>
   <summary>
@@ -1412,7 +1412,7 @@
 </histogram>
 
 <histogram name="PageLoad.Clients.{Origin}.LargestContentfulPaint" units="ms"
-    expires_after="2024-02-29">
+    expires_after="2024-05-05">
   <owner>chikamune@chromium.org</owner>
   <owner>loading-dev@chromium.org</owner>
   <summary>
@@ -1427,7 +1427,7 @@
 
 <histogram
     name="PageLoad.Clients.{Origin}.LayoutInstability.CumulativeShiftScore"
-    units="ms" expires_after="2024-02-29">
+    units="ms" expires_after="2024-05-05">
   <owner>chikamune@chromium.org</owner>
   <owner>loading-dev@chromium.org</owner>
   <summary>
@@ -1973,7 +1973,7 @@
 </histogram>
 
 <histogram name="PageLoad.Experimental.PageVisitType2" enum="PageVisitType"
-    expires_after="2024-02-25">
+    expires_after="2024-05-05">
   <owner>toyoshim@chromium.org</owner>
   <owner>chrome-prerendering@google.com</owner>
   <summary>
@@ -2459,7 +2459,7 @@
 
 <histogram
     name="PageLoad.Internal.PaintTiming.LargestContentfulPaint.ContentType"
-    enum="LargestContentType" expires_after="2024-03-03">
+    enum="LargestContentType" expires_after="2024-05-05">
   <owner>iclelland@chromium.org</owner>
   <owner>speed-metrics-dev@chromium.org</owner>
   <summary>
@@ -2576,7 +2576,7 @@
 </histogram>
 
 <histogram name="PageLoad.Internal.SuppressedEventsCountBeforePaint"
-    units="count" expires_after="2024-03-01">
+    units="count" expires_after="2024-05-05">
   <owner>mustaq@chromium.org</owner>
   <owner>blink-interactions-team@google.com</owner>
   <summary>
@@ -2594,7 +2594,7 @@
 </histogram>
 
 <histogram name="PageLoad.Internal.SuppressedEventsTimingBeforePaint"
-    units="ms" expires_after="2024-03-01">
+    units="ms" expires_after="2024-05-05">
   <owner>mustaq@chromium.org</owner>
   <owner>blink-interactions-team@google.com</owner>
   <summary>
@@ -2616,7 +2616,7 @@
 </histogram>
 
 <histogram name="PageLoad.Internal.SuppressedInteractionsCountBeforePaint"
-    units="count" expires_after="2024-03-01">
+    units="count" expires_after="2024-05-05">
   <owner>mustaq@chromium.org</owner>
   <owner>blink-interactions-team@google.com</owner>
   <summary>
@@ -3115,7 +3115,7 @@
 </histogram>
 
 <histogram name="PageLoad.ParseTiming.ParseBlockedOnScriptExecution" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>cduvall@chromium.org</owner>
   <owner>swarm-team@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/password/histograms.xml b/tools/metrics/histograms/metadata/password/histograms.xml
index b07ccab..f931b07 100644
--- a/tools/metrics/histograms/metadata/password/histograms.xml
+++ b/tools/metrics/histograms/metadata/password/histograms.xml
@@ -694,7 +694,7 @@
 </histogram>
 
 <histogram name="PasswordManager.AffiliationDatabase.StoreResult"
-    enum="StoreAffiliationResult" expires_after="2024-03-03">
+    enum="StoreAffiliationResult" expires_after="2024-05-05">
   <owner>vsemeniuk@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>The result of AffiliationDatabase::Store call.</summary>
@@ -743,7 +743,7 @@
 </histogram>
 
 <histogram name="PasswordManager.AffiliationFetcher.FetchTime.{Status}"
-    units="ms" expires_after="M123">
+    units="ms" expires_after="2024-05-05">
   <owner>vsemeniuk@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -772,7 +772,7 @@
 </histogram>
 
 <histogram name="PasswordManager.AffiliationService.GetChangePasswordUsage"
-    enum="GetChangePasswordUrlMetric" expires_after="M123">
+    enum="GetChangePasswordUrlMetric" expires_after="2024-05-05">
   <owner>vsemeniuk@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -1045,7 +1045,7 @@
 </histogram>
 
 <histogram name="PasswordManager.BulkCheck.TimePerCredential" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>vasilii@chromium.org</owner>
   <owner>vsemeniuk@google.com</owner>
   <summary>
@@ -1159,7 +1159,7 @@
 
 <histogram
     name="PasswordManager.CredentialManager.{ProfileType}.GetIntent.APIError"
-    enum="PasswordStoreAndroidBackendAPIError" expires_after="M123">
+    enum="PasswordStoreAndroidBackendAPIError" expires_after="2024-05-05">
   <owner>ioanap@chromium.org</owner>
   <owner>izuzic@google.com</owner>
   <summary>
@@ -1187,7 +1187,7 @@
 
 <histogram
     name="PasswordManager.CredentialManager.{ProfileType}.GetIntent.Error"
-    enum="CredentialManagerError" expires_after="M123">
+    enum="CredentialManagerError" expires_after="2024-05-05">
   <owner>ioanap@chromium.org</owner>
   <owner>fhorschig@chromium.org</owner>
   <summary>
@@ -1478,7 +1478,7 @@
 </histogram>
 
 <histogram name="PasswordManager.FillSuggestionsIncludeAndroidAppCredentials"
-    enum="PasswordManagerOfferedAndroidCredentials" expires_after="2024-03-01">
+    enum="PasswordManagerOfferedAndroidCredentials" expires_after="2024-05-05">
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -1808,7 +1808,7 @@
 </histogram>
 
 <histogram name="PasswordManager.IsPasswordProtected2" enum="Boolean"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>skrakowi@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -1920,7 +1920,7 @@
 </histogram>
 
 <histogram name="PasswordManager.LeakDetection.ObtainAccessTokenTime"
-    units="ms" expires_after="M123">
+    units="ms" expires_after="2024-05-05">
   <owner>vsemeniuk@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -2114,7 +2114,7 @@
 </histogram>
 
 <histogram name="PasswordManager.MigrationToOSCrypt{StoreType}"
-    enum="MigrationToOSCryptEnum" expires_after="2024-03-03">
+    enum="MigrationToOSCryptEnum" expires_after="2024-05-05">
   <owner>vsemeniuk@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -2779,7 +2779,7 @@
 
 <histogram
     name="PasswordManager.PasswordStoreAndroidBackend.Retry{Operation}.APIError"
-    enum="PasswordStoreAndroidBackendAPIError" expires_after="M123">
+    enum="PasswordStoreAndroidBackendAPIError" expires_after="2024-05-05">
   <owner>izuzic@google.com</owner>
   <owner>ioanap@chromium.org</owner>
   <summary>
@@ -3008,7 +3008,7 @@
 </histogram>
 
 <histogram name="PasswordManager.PasswordSyncState3" enum="PasswordSyncState"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -3116,7 +3116,7 @@
 </histogram>
 
 <histogram name="PasswordManager.ProvisionalSaveFailure2"
-    enum="ProvisionalSaveFailure" expires_after="2024-03-03">
+    enum="ProvisionalSaveFailure" expires_after="2024-05-05">
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
@@ -3218,7 +3218,7 @@
 
 <histogram
     name="PasswordManager.SavedGaiaPasswordHashCount2{SyncConsentStatus}"
-    units="count" expires_after="2024-03-03">
+    units="count" expires_after="2024-05-05">
   <owner>vsemeniuk@google.com</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -3554,7 +3554,7 @@
 </histogram>
 
 <histogram name="PasswordManager.TimeBetweenStoreAndServer" units="ms"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>kazinova@google.com</owner>
   <owner>battre@chromium.org</owner>
   <summary>
@@ -3736,7 +3736,7 @@
 
 <histogram
     name="PasswordManager.UnifiedPasswordManager.{UPMMigrationType}.Latency"
-    units="ms" expires_after="M123">
+    units="ms" expires_after="2024-05-05">
   <owner>vsemeniuk@google.com</owner>
   <owner>fhorschig@chromium.org</owner>
   <summary>
@@ -3748,7 +3748,7 @@
 
 <histogram
     name="PasswordManager.UnifiedPasswordManager.{UPMMigrationType}.Success"
-    enum="BooleanSuccess" expires_after="M123">
+    enum="BooleanSuccess" expires_after="2024-05-05">
   <owner>vsemeniuk@google.com</owner>
   <owner>fhorschig@chromium.org</owner>
   <summary>
@@ -4191,7 +4191,7 @@
 </histogram>
 
 <histogram name="PasswordProtection.RequestWithToken.{TriggerType}"
-    enum="BooleanSent" expires_after="2024-03-02">
+    enum="BooleanSent" expires_after="2024-05-05">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/performance_manager/histograms.xml b/tools/metrics/histograms/metadata/performance_manager/histograms.xml
index 87173d93..1f604de 100644
--- a/tools/metrics/histograms/metadata/performance_manager/histograms.xml
+++ b/tools/metrics/histograms/metadata/performance_manager/histograms.xml
@@ -297,7 +297,7 @@
 </histogram>
 
 <histogram name="PerformanceManager.UserTuning.BatterySaverModeEnabledPercent"
-    units="%" expires_after="2024-03-03">
+    units="%" expires_after="2024-05-05">
   <owner>anthonyvd@chromium.org</owner>
   <owner>chrome-catan@google.com</owner>
   <summary>
@@ -321,7 +321,7 @@
 </histogram>
 
 <histogram name="PerformanceManager.UserTuning.MemorySaverModeEnabledPercent"
-    units="%" expires_after="2024-03-03">
+    units="%" expires_after="2024-05-05">
   <owner>anthonyvd@chromium.org</owner>
   <owner>chrome-catan@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/permissions/histograms.xml b/tools/metrics/histograms/metadata/permissions/histograms.xml
index 834698a..e644b366 100644
--- a/tools/metrics/histograms/metadata/permissions/histograms.xml
+++ b/tools/metrics/histograms/metadata/permissions/histograms.xml
@@ -353,7 +353,7 @@
 </histogram>
 
 <histogram name="Permissions.ConfirmationChip.PageInfoDialogAccessType"
-    enum="PageInfoDialogAccessType" expires_after="2024-03-03">
+    enum="PageInfoDialogAccessType" expires_after="2024-05-05">
   <owner>fjacky@chromium.org</owner>
   <owner>src/components/permissions/PERMISSIONS_OWNERS</owner>
   <summary>
@@ -1325,7 +1325,7 @@
 </histogram>
 
 <histogram base="true" name="Permissions.Revocation.ElapsedTimeSinceGrant"
-    units="seconds" expires_after="2024-03-03">
+    units="seconds" expires_after="2024-05-05">
   <owner>engedy@chromium.org</owner>
   <owner>src/components/permissions/PERMISSIONS_OWNERS</owner>
   <summary>
@@ -1335,7 +1335,7 @@
 </histogram>
 
 <histogram name="Permissions.Revocation.Notifications.DidRecordUkm"
-    enum="Boolean" expires_after="2024-03-03">
+    enum="Boolean" expires_after="2024-05-05">
   <owner>engedy@chromium.org</owner>
   <owner>willxu@google.com</owner>
   <owner>src/components/permissions/PERMISSIONS_OWNERS</owner>
@@ -1485,7 +1485,7 @@
 </histogram>
 
 <histogram name="WebsiteSettings.AllSitesAction2"
-    enum="WebSiteSettingsAllSitesAction2" expires_after="2024-03-03">
+    enum="WebSiteSettingsAllSitesAction2" expires_after="2024-05-05">
   <owner>sauski@google.com</owner>
   <owner>alimariam@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/phonehub/histograms.xml b/tools/metrics/histograms/metadata/phonehub/histograms.xml
index 386ed6b..e12af04f 100644
--- a/tools/metrics/histograms/metadata/phonehub/histograms.xml
+++ b/tools/metrics/histograms/metadata/phonehub/histograms.xml
@@ -73,7 +73,7 @@
 </histogram>
 
 <histogram name="PhoneHub.BubbleOpened.Connectable.Failed.HostLastSeen"
-    units="ms" expires_after="2024-03-03">
+    units="ms" expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -83,7 +83,7 @@
 </histogram>
 
 <histogram name="PhoneHub.BubbleOpened.Connectable.Page" enum="PhoneHubScreen"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -95,7 +95,7 @@
 
 <histogram name="PhoneHub.CameraRoll.AndroidHasStoragePermission"
     enum="PhoneHubCameraRollBooleanStorageAccessPermission"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -106,7 +106,7 @@
 </histogram>
 
 <histogram name="PhoneHub.CameraRoll.Content.Clicked{MediaType}"
-    enum="PhoneHubCameraRollContentClicked" expires_after="2024-03-03">
+    enum="PhoneHubCameraRollContentClicked" expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -117,7 +117,7 @@
 </histogram>
 
 <histogram name="PhoneHub.CameraRoll.Content.Present" enum="BooleanPresent"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jasonsun@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -128,7 +128,7 @@
 </histogram>
 
 <histogram name="PhoneHub.CameraRoll.Content.Shown{MediaType}"
-    enum="PhoneHubCameraRollContentShown" expires_after="2024-03-03">
+    enum="PhoneHubCameraRollContentShown" expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -139,7 +139,7 @@
 </histogram>
 
 <histogram name="PhoneHub.CameraRoll.ContextMenu.Download{MediaType}"
-    enum="PhoneHubCameraRollContextMenuDownload" expires_after="2024-03-03">
+    enum="PhoneHubCameraRollContextMenuDownload" expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -150,7 +150,7 @@
 </histogram>
 
 <histogram name="PhoneHub.CameraRoll.DownloadItem.Result"
-    enum="PhoneHubCameraRollDownloadResult" expires_after="2024-03-03">
+    enum="PhoneHubCameraRollDownloadResult" expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -160,7 +160,7 @@
 </histogram>
 
 <histogram name="PhoneHub.CameraRoll.DownloadItem.TransferRate" units="KB/s"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jasonsun@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -171,7 +171,7 @@
 </histogram>
 
 <histogram name="PhoneHub.CameraRoll.Latency.RefreshItems" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jasonsun@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -182,7 +182,7 @@
 </histogram>
 
 <histogram name="PhoneHub.CameraRoll.OptInEntryPoint"
-    enum="PhoneHubCameraRollOptInEntryPoint" expires_after="2024-03-03">
+    enum="PhoneHubCameraRollOptInEntryPoint" expires_after="2024-05-05">
   <owner>jianbing@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -209,7 +209,7 @@
 </histogram>
 
 <histogram name="PhoneHub.CompletedUserAction" enum="PhoneHubUserAction"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -221,7 +221,7 @@
 </histogram>
 
 <histogram name="PhoneHub.Connection.Duration" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -231,7 +231,7 @@
 </histogram>
 
 <histogram name="PhoneHub.Connection.Latency" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>crisrael@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -241,7 +241,7 @@
 </histogram>
 
 <histogram name="PhoneHub.Connection.Result" enum="BooleanSuccess"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -255,7 +255,7 @@
 
 <histogram name="PhoneHub.Connection.Result.FailureReason"
     enum="SecureChannelConnectionAttemptFailureReason"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -280,7 +280,7 @@
 </histogram>
 
 <histogram name="PhoneHub.InitialPhoneStatusSnapshot.Latency" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>pushi@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -291,7 +291,7 @@
 </histogram>
 
 <histogram name="PhoneHub.InitialPhoneStatusSnapshot.Received"
-    enum="BooleanSuccess" expires_after="2024-03-03">
+    enum="BooleanSuccess" expires_after="2024-05-05">
   <owner>pushi@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -353,7 +353,7 @@
 </histogram>
 
 <histogram name="PhoneHub.MultiDeviceFeatureState{PhoneHubFeature}"
-    enum="MultiDevice_FeatureState" expires_after="2024-03-03">
+    enum="MultiDevice_FeatureState" expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -401,7 +401,7 @@
 </histogram>
 
 <histogram name="PhoneHub.NotificationCount" units="notifications"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -411,7 +411,7 @@
 </histogram>
 
 <histogram name="PhoneHub.NotificationInteraction"
-    enum="PhoneHubNotificationInteraction" expires_after="2024-03-03">
+    enum="PhoneHubNotificationInteraction" expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -421,7 +421,7 @@
 </histogram>
 
 <histogram name="PhoneHub.NotificationMessageLength" units="characters"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -442,7 +442,7 @@
 </histogram>
 
 <histogram name="PhoneHub.OptInEntryPoint" enum="PhoneHubOptInEntryPoint"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>Tracks the UI surface with which users enable Phone Hub.</summary>
@@ -450,7 +450,7 @@
 
 <histogram
     name="PhoneHub.PermissionsOnboarding.DialogScreenEvents.{SetupScreen}Screen"
-    enum="PhoneHubPermissionsOnboardingScreenEvent" expires_after="2024-03-03">
+    enum="PhoneHubPermissionsOnboardingScreenEvent" expires_after="2024-05-05">
   <owner>jianbing@google.com</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -534,14 +534,14 @@
 </histogram>
 
 <histogram name="PhoneHub.QuickActionClicked" enum="PhoneHubQuickAction"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>Event logged after the user clicks on a quick action.</summary>
 </histogram>
 
 <histogram name="PhoneHub.RecentApps.State.OnBubbleOpened"
-    enum="RecentAppsViewUiState" expires_after="2024-03-03">
+    enum="RecentAppsViewUiState" expires_after="2024-05-05">
   <owner>crisrael@google.com</owner>
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
@@ -551,7 +551,7 @@
 </histogram>
 
 <histogram name="PhoneHub.RecentApps.TransitionToFailed.Latency" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>crisrael@google.com</owner>
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
@@ -562,7 +562,7 @@
 </histogram>
 
 <histogram name="PhoneHub.RecentApps.TransitionToSuccess.Latency" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>crisrael@google.com</owner>
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
@@ -583,7 +583,7 @@
 </histogram>
 
 <histogram name="PhoneHub.ScreenOn{BubbleEvent}" enum="PhoneHubScreen"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -597,7 +597,7 @@
 </histogram>
 
 <histogram name="PhoneHub.TabContinuationChipClicked" units="tab index"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -608,7 +608,7 @@
 </histogram>
 
 <histogram name="PhoneHub.TaskCompletion.TetherConnection.Result"
-    enum="PhoneHubTetherConnectionResult" expires_after="2024-03-03">
+    enum="PhoneHubTetherConnectionResult" expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -618,7 +618,7 @@
 </histogram>
 
 <histogram name="PhoneHub.TaskCompletion.{MessageType}.Result"
-    enum="PhoneHubMessageResult" expires_after="2024-03-03">
+    enum="PhoneHubMessageResult" expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
@@ -662,7 +662,7 @@
 </histogram>
 
 <histogram name="PhoneHub.Usage.SentMessageTypeCount"
-    enum="PhoneHubMessageType" expires_after="2023-12-31">
+    enum="PhoneHubMessageType" expires_after="2024-05-05">
   <owner>jonmann@chromium.org</owner>
   <owner>chromeos-cross-device-eng@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/platform/histograms.xml b/tools/metrics/histograms/metadata/platform/histograms.xml
index 7acfec6..d12cdc7 100644
--- a/tools/metrics/histograms/metadata/platform/histograms.xml
+++ b/tools/metrics/histograms/metadata/platform/histograms.xml
@@ -610,7 +610,7 @@
 </histogram>
 
 <histogram name="Platform.FlexPartitionSize.{Partition}" units="MiB"
-    expires_after="2024-02-01">
+    expires_after="2024-05-05">
   <owner>nicholasbishop@google.com</owner>
   <owner>chromeos-flex-eng@google.com</owner>
   <summary>
@@ -992,7 +992,7 @@
 
 <histogram
     name="Platform.Libhwsec.PinWeaverManager.SyncHashTree.ReplayLogResult{ReplayType}"
-    enum="HwsecPinWeaverLogReplayResultEnum" expires_after="2024-02-20">
+    enum="HwsecPinWeaverLogReplayResultEnum" expires_after="2024-05-05">
   <owner>chensa@google.com</owner>
   <owner>cros-hwsec-userland-eng+uma@google.com</owner>
   <summary>
@@ -1011,7 +1011,7 @@
 </histogram>
 
 <histogram name="Platform.Libhwsec.PinWeaverManager.SyncHashTree.SyncOutcome"
-    enum="HwsecPinWeaverSyncOutcomeEnum" expires_after="2024-02-20">
+    enum="HwsecPinWeaverSyncOutcomeEnum" expires_after="2024-05-05">
   <owner>chensa@google.com</owner>
   <owner>cros-hwsec-userland-eng+uma@google.com</owner>
   <summary>
@@ -1616,7 +1616,7 @@
 </histogram>
 
 <histogram name="Platform.Missive.UploadToStorageRate.{Priority}" units="%"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>lbaraz@chromium.org</owner>
   <owner>cros-reporting-team@google.com</owner>
   <summary>
@@ -1697,7 +1697,7 @@
 </histogram>
 
 <histogram name="Platform.Modemfwd.ModemRecoveryState"
-    enum="ModemfwdModemRecoveryState" expires_after="2024-03-06">
+    enum="ModemfwdModemRecoveryState" expires_after="2024-05-05">
   <owner>ujjwalpande@google.com</owner>
   <owner>cros-connectivity@google.com</owner>
   <summary>Report state of modem recovery operation.</summary>
diff --git a/tools/metrics/histograms/metadata/plugin_vm/histograms.xml b/tools/metrics/histograms/metadata/plugin_vm/histograms.xml
index 62e614a..5d95f02 100644
--- a/tools/metrics/histograms/metadata/plugin_vm/histograms.xml
+++ b/tools/metrics/histograms/metadata/plugin_vm/histograms.xml
@@ -30,7 +30,7 @@
 </histogram>
 
 <histogram name="PluginVm.EngagementTime.Background" units="ms"
-    expires_after="2024-01-14">
+    expires_after="2024-05-05">
   <owner>timloh@google.com</owner>
   <owner>joelhockey@google.com</owner>
   <summary>
@@ -41,7 +41,7 @@
 </histogram>
 
 <histogram name="PluginVm.EngagementTime.Foreground" units="ms"
-    expires_after="2024-02-11">
+    expires_after="2024-05-05">
   <owner>timloh@google.com</owner>
   <owner>joelhockey@google.com</owner>
   <summary>
@@ -51,7 +51,7 @@
 </histogram>
 
 <histogram name="PluginVm.EngagementTime.PluginVmTotal" units="ms"
-    expires_after="2024-02-11">
+    expires_after="2024-05-05">
   <owner>timloh@google.com</owner>
   <owner>joelhockey@google.com</owner>
   <summary>
@@ -62,7 +62,7 @@
 </histogram>
 
 <histogram name="PluginVm.EngagementTime.Total" units="ms"
-    expires_after="2024-02-11">
+    expires_after="2024-05-05">
   <owner>timloh@google.com</owner>
   <owner>joelhockey@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/power/histograms.xml b/tools/metrics/histograms/metadata/power/histograms.xml
index 46e4a463..11153c06 100644
--- a/tools/metrics/histograms/metadata/power/histograms.xml
+++ b/tools/metrics/histograms/metadata/power/histograms.xml
@@ -2041,7 +2041,7 @@
 </histogram>
 
 <histogram name="Power.PeripheralReadErrorLatencyMs" units="ms"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>skyostil@chromium.org</owner>
   <owner>chromeos-platform-power@google.com</owner>
   <summary>
@@ -2051,7 +2051,7 @@
 </histogram>
 
 <histogram name="Power.PeripheralReadLatencyMs" units="ms"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>skyostil@chromium.org</owner>
   <owner>chromeos-platform-power@google.com</owner>
   <summary>
@@ -2217,7 +2217,7 @@
   </summary>
 </histogram>
 
-<histogram name="Power.SuspendDelay" units="seconds" expires_after="2024-03-03">
+<histogram name="Power.SuspendDelay" units="seconds" expires_after="2024-05-05">
   <owner>niwa@chromium.org</owner>
   <owner>puthik@chromium.org</owner>
   <owner>chromeos-platform-power@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/printing/histograms.xml b/tools/metrics/histograms/metadata/printing/histograms.xml
index 2d6d1e8..b807944 100644
--- a/tools/metrics/histograms/metadata/printing/histograms.xml
+++ b/tools/metrics/histograms/metadata/printing/histograms.xml
@@ -33,7 +33,7 @@
 </histogram>
 
 <histogram name="Printing.ConversionSize.EmfWithReducedRasterization"
-    units="KB" expires_after="2024-03-03">
+    units="KB" expires_after="2024-05-05">
   <owner>thestig@chromium.org</owner>
   <owner>awscreen@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/privacy/histograms.xml b/tools/metrics/histograms/metadata/privacy/histograms.xml
index 25be2f8..273fb39 100644
--- a/tools/metrics/histograms/metadata/privacy/histograms.xml
+++ b/tools/metrics/histograms/metadata/privacy/histograms.xml
@@ -687,7 +687,7 @@
 
 <histogram
     name="PrivacySandbox.Attestations.InitializationDuration.ComponentReadyFromApplicationStart"
-    units="ms" expires_after="M122">
+    units="ms" expires_after="2024-05-05">
   <owner>shivanisha@chromium.org</owner>
   <owner>xiaochenzh@chromium.org</owner>
   <summary>
@@ -699,7 +699,7 @@
 
 <histogram
     name="PrivacySandbox.Attestations.InitializationDuration.ComponentReadyFromApplicationStartWithInterruption"
-    units="ms" expires_after="M122">
+    units="ms" expires_after="2024-05-05">
   <owner>shivanisha@chromium.org</owner>
   <owner>xiaochenzh@chromium.org</owner>
   <summary>
@@ -714,7 +714,7 @@
 
 <histogram
     name="PrivacySandbox.Attestations.InitializationDuration.ComponentReadyFromBrowserWindowFirstPaint"
-    units="ms" expires_after="M122">
+    units="ms" expires_after="2024-05-05">
   <owner>shivanisha@chromium.org</owner>
   <owner>xiaochenzh@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/profile/histograms.xml b/tools/metrics/histograms/metadata/profile/histograms.xml
index 730a361..5b1702a 100644
--- a/tools/metrics/histograms/metadata/profile/histograms.xml
+++ b/tools/metrics/histograms/metadata/profile/histograms.xml
@@ -54,7 +54,7 @@
   </summary>
 </histogram>
 
-<histogram name="Profile.AppCount" units="units" expires_after="2024-03-03">
+<histogram name="Profile.AppCount" units="units" expires_after="2024-05-05">
   <owner>etienneb@chromium.org</owner>
   <owner>gab@chromium.org</owner>
   <summary>The number of installed apps when a profile is opened.</summary>
@@ -610,7 +610,7 @@
   </summary>
 </histogram>
 
-<histogram name="Profile.{Database}Size" units="MB" expires_after="2024-03-03">
+<histogram name="Profile.{Database}Size" units="MB" expires_after="2024-05-05">
   <owner>etienneb@chromium.org</owner>
   <owner>gab@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/quick_answers/histograms.xml b/tools/metrics/histograms/metadata/quick_answers/histograms.xml
index e803438..46fe780 100644
--- a/tools/metrics/histograms/metadata/quick_answers/histograms.xml
+++ b/tools/metrics/histograms/metadata/quick_answers/histograms.xml
@@ -285,7 +285,7 @@
 </histogram>
 
 <histogram name="QuickAnswers.TextToSpeech.EngineEvent"
-    enum="QuickAnswersTextToSpeechEngineEvent" expires_after="2023-12-24">
+    enum="QuickAnswersTextToSpeechEngineEvent" expires_after="2024-05-05">
   <owner>angelaxiao@chromium.org</owner>
   <owner>yawano@google.com</owner>
   <owner>croissant-eng@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/quota/histograms.xml b/tools/metrics/histograms/metadata/quota/histograms.xml
index 6bb8ab6..d615057 100644
--- a/tools/metrics/histograms/metadata/quota/histograms.xml
+++ b/tools/metrics/histograms/metadata/quota/histograms.xml
@@ -78,7 +78,7 @@
 </histogram>
 
 <histogram name="Quota.DatabaseSpecificError.{Statement}"
-    enum="SqliteLoggedResultCode" expires_after="2024-03-03">
+    enum="SqliteLoggedResultCode" expires_after="2024-05-05">
   <owner>estade@chromium.org</owner>
   <owner>chrome-owp-storage@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 cac10d7e..828c1ecd 100644
--- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
+++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -844,7 +844,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.ExtensionTelemetry.Signals.Discarded"
-    enum="SBExtensionTelemetrySignalsSignalType" expires_after="2024-03-03">
+    enum="SBExtensionTelemetrySignalsSignalType" expires_after="2024-05-05">
   <owner>anunoy@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -978,7 +978,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.GmsSafeBrowsingApi.CheckDelta{Protocol}"
-    units="microseconds" expires_after="2024-03-01">
+    units="microseconds" expires_after="2024-05-05">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -996,7 +996,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.GmsSafeBrowsingApi.IsAvailable{Protocol}"
-    enum="BooleanAvailable" expires_after="2024-03-01">
+    enum="BooleanAvailable" expires_after="2024-05-05">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -1024,7 +1024,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.GmsSafeBrowsingApi.LookupResult{Protocol}"
-    enum="SafeBrowsingApiLookupResult" expires_after="2024-03-01">
+    enum="SafeBrowsingApiLookupResult" expires_after="2024-05-05">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -1041,7 +1041,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.GmsSafeBrowsingApi.ResponseStatus{Protocol}"
-    enum="SafeBrowsingApiResponseStatus" expires_after="2024-03-01">
+    enum="SafeBrowsingApiResponseStatus" expires_after="2024-05-05">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -1217,7 +1217,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.HPRT.CanGetReputationOfUrl"
-    enum="BooleanCanCheckUrl" expires_after="2024-03-01">
+    enum="BooleanCanCheckUrl" expires_after="2024-05-05">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -1229,7 +1229,7 @@
 
 <histogram
     name="SafeBrowsing.HPRT.FailedNetResultIsFromEarlyOhttpClientDestruct"
-    enum="BooleanYesNo" expires_after="2024-02-04">
+    enum="BooleanYesNo" expires_after="2024-05-05">
   <owner>thefrog@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -2307,7 +2307,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.RT.Request.ReferrerChainLength{UserCategory}"
-    units="units" expires_after="2024-03-02">
+    units="units" expires_after="2024-05-05">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -2714,7 +2714,7 @@
 </histogram>
 
 <histogram name="SafeBrowsing.V4GetHash.CountOfPrefixes" units="prefixes"
-    expires_after="2024-02-25">
+    expires_after="2024-05-05">
   <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 54743af..e4c1ec288 100644
--- a/tools/metrics/histograms/metadata/sb_client/histograms.xml
+++ b/tools/metrics/histograms/metadata/sb_client/histograms.xml
@@ -300,7 +300,7 @@
 </histogram>
 
 <histogram name="SBClientDownload.SafeDownloadOpenedLatency2.{ShowAction}"
-    units="ms" expires_after="2024-03-02">
+    units="ms" expires_after="2024-05-05">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -387,7 +387,7 @@
 
 <histogram
     name="SBClientDownload.Warning.DownloadHasUserGesture.{DangerType}.{Action}"
-    enum="BooleanHasUserGesture" expires_after="2024-03-02">
+    enum="BooleanHasUserGesture" expires_after="2024-05-05">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
@@ -424,7 +424,7 @@
 </histogram>
 
 <histogram name="SBClientDownload.Warning.FileType.{DangerType}.{Action}"
-    enum="SBClientDownloadExtensions" expires_after="2024-03-02">
+    enum="SBClientDownloadExtensions" expires_after="2024-05-05">
   <owner>xinghuilu@chromium.org</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/search/histograms.xml b/tools/metrics/histograms/metadata/search/histograms.xml
index 9f4ade8..b756c7f 100644
--- a/tools/metrics/histograms/metadata/search/histograms.xml
+++ b/tools/metrics/histograms/metadata/search/histograms.xml
@@ -1805,7 +1805,7 @@
 </histogram>
 
 <histogram name="Search.RelatedSearches.CarouselLastVisibleItemPosition"
-    units="position" expires_after="2024-03-03">
+    units="position" expires_after="2024-05-05">
   <owner>donnd@chromium.org</owner>
   <owner>gangwu@chromium.org</owner>
   <owner>related-searches-vteam@google.com</owner>
@@ -1831,7 +1831,7 @@
 </histogram>
 
 <histogram name="Search.RelatedSearches.CarouselScrolled" enum="Boolean"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>donnd@chromium.org</owner>
   <owner>gangwu@chromium.org</owner>
   <owner>related-searches-vteam@google.com</owner>
@@ -1870,7 +1870,7 @@
 </histogram>
 
 <histogram name="Search.RelatedSearches.QualifiedUsers" enum="Boolean"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>gangwu@chromium.org</owner>
   <owner>related-searches-vteam@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/security/histograms.xml b/tools/metrics/histograms/metadata/security/histograms.xml
index 4feea17..fa0ed806 100644
--- a/tools/metrics/histograms/metadata/security/histograms.xml
+++ b/tools/metrics/histograms/metadata/security/histograms.xml
@@ -302,7 +302,7 @@
 </histogram>
 
 <histogram name="Security.NavigationRequestSecurityLevel"
-    enum="NavigationRequestSecurityLevel" expires_after="2024-03-01">
+    enum="NavigationRequestSecurityLevel" expires_after="2024-05-05">
   <owner>jdeblasio@chromium.org</owner>
   <owner>trusty-transport@chromium.org</owner>
   <summary>
@@ -453,7 +453,7 @@
 </histogram>
 
 <histogram name="Security.PrivateNetworkAccess.PrivateIpResolveMatch"
-    enum="Boolean" expires_after="2024-03-03">
+    enum="Boolean" expires_after="2024-05-05">
   <owner>titouan@chromium.org</owner>
   <owner>lyf@chromium.org</owner>
   <owner>clamy@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/service/histograms.xml b/tools/metrics/histograms/metadata/service/histograms.xml
index 16cb86e..fcacf6b 100644
--- a/tools/metrics/histograms/metadata/service/histograms.xml
+++ b/tools/metrics/histograms/metadata/service/histograms.xml
@@ -505,7 +505,7 @@
 
 <histogram
     name="ServiceWorker.FetchEvent.{Resource}.RaceNetworkRequest.Redirect"
-    enum="Boolean" expires_after="2024-01-14">
+    enum="Boolean" expires_after="2024-05-05">
   <owner>sisidovski@chromium.org</owner>
   <owner>chrome-worker@google.com</owner>
   <summary>
@@ -1492,7 +1492,7 @@
 </histogram>
 
 <histogram name="ServiceWorker.StartWorker.Timeout.StartPurpose"
-    enum="ServiceWorkerMetrics.EventType" expires_after="2024-03-03">
+    enum="ServiceWorkerMetrics.EventType" expires_after="2024-05-05">
   <owner>chikamune@chromium.org</owner>
   <owner>chrome-worker@google.com</owner>
   <summary>
@@ -1504,7 +1504,7 @@
 </histogram>
 
 <histogram name="ServiceWorker.StartWorker.TimeoutPhase"
-    enum="EmbeddedWorkerStartingPhase" expires_after="2024-03-03">
+    enum="EmbeddedWorkerStartingPhase" expires_after="2024-05-05">
   <owner>chikamune@chromium.org</owner>
   <owner>chrome-worker@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/session/histograms.xml b/tools/metrics/histograms/metadata/session/histograms.xml
index f49db96..c1de2d71 100644
--- a/tools/metrics/histograms/metadata/session/histograms.xml
+++ b/tools/metrics/histograms/metadata/session/histograms.xml
@@ -872,7 +872,7 @@
 </histogram>
 
 <histogram name="Session.WebStates.LoadingTimeOnMainThread" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>fedegermi@chromium.org</owner>
   <owner>sdefresne@chromium.org</owner>
   <summary>
@@ -963,7 +963,7 @@
 </histogram>
 
 <histogram name="Session.WebStates.SavingTimeOnMainThread" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>fedegermi@chromium.org</owner>
   <owner>sdefresne@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/sharing/histograms.xml b/tools/metrics/histograms/metadata/sharing/histograms.xml
index 933289d..d72f912 100644
--- a/tools/metrics/histograms/metadata/sharing/histograms.xml
+++ b/tools/metrics/histograms/metadata/sharing/histograms.xml
@@ -391,7 +391,7 @@
 </histogram>
 
 <histogram name="Sharing.SmsFetcherAvailableDeviceCount" units="devices"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>yigu@chromium.org</owner>
   <owner>src/content/browser/sms/OWNERS</owner>
   <summary>
@@ -413,7 +413,7 @@
 </histogram>
 
 <histogram name="Sharing.SmsFetcherScreenOnAndUnlocked" enum="Boolean"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>yigu@chromium.org</owner>
   <owner>src/content/browser/sms/OWNERS</owner>
   <summary>
@@ -424,7 +424,7 @@
 </histogram>
 
 <histogram name="Sharing.SmsFetcherTapWithChromeDestroyed" enum="Boolean"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>yigu@chromium.org</owner>
   <owner>src/content/browser/sms/OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/side_search/histograms.xml b/tools/metrics/histograms/metadata/side_search/histograms.xml
index 1666ff96..2908c607 100644
--- a/tools/metrics/histograms/metadata/side_search/histograms.xml
+++ b/tools/metrics/histograms/metadata/side_search/histograms.xml
@@ -72,7 +72,7 @@
 </histogram>
 
 <histogram name="SideSearch.LoadDocumentTime" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>yuhengh@chromium.org</owner>
   <owner>tluk@chromium.org</owner>
   <owner>romanarora@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/signin/histograms.xml b/tools/metrics/histograms/metadata/signin/histograms.xml
index 666f734..aad53944 100644
--- a/tools/metrics/histograms/metadata/signin/histograms.xml
+++ b/tools/metrics/histograms/metadata/signin/histograms.xml
@@ -403,6 +403,36 @@
   </summary>
 </histogram>
 
+<histogram name="Signin.Bookmarks.{ConsentLevel}.{BookmarkGroup}{AccessPoint}"
+    units="count" expires_after="2024-03-22">
+  <owner>rsult@google.com</owner>
+  <owner>droger@chromium.org</owner>
+  <owner>chrome-signin-team@google.com</owner>
+  <summary>
+    Recording the count of {BookmarkGroup}. The record happens when the user is
+    {ConsentLevel} Chrome via {AccessPoint} access point.
+  </summary>
+  <token key="ConsentLevel">
+    <variant name="OnSignin" summary="signing in to"/>
+    <variant name="OnSync" summary="enabling sync in"/>
+  </token>
+  <token key="BookmarkGroup">
+    <variant name="AllBookmarks" summary="all bookmarks"/>
+    <variant name="BookmarksBar"
+        summary="bookmarks in the main bar (only bookmarks on the first layer
+                 of the bar, folder counts as 1, disregarding sub-folder or
+                 bookmarks in folders)"/>
+  </token>
+  <token key="AccessPoint">
+    <variant name="" summary="any"/>
+    <variant name=".Other" summary="any other"/>
+    <variant name=".PreUnoWebSignin" summary="a regular web sign in (pre UNO)"/>
+    <variant name=".ProfileCreation" summary="any profile creation"/>
+    <variant name=".ProfileMenu" summary="the profile menu (avatar button)"/>
+    <variant name=".UnoSigninBubble" summary="the Chrome Signin bubble"/>
+  </token>
+</histogram>
+
 <histogram
     name="Signin.BoundSessionCredentials.CookieRotationGenerateAssertionDuration"
     units="ms" expires_after="2024-04-28">
@@ -494,6 +524,20 @@
   </summary>
 </histogram>
 
+<histogram
+    name="Signin.BoundSessionCredentials.ThrottledRequestsSuccessiveTimeout"
+    units="timeouts" expires_after="2024-01-14">
+  <owner>alexilin@chromium.org</owner>
+  <owner>msalama@chromium.org</owner>
+  <owner>chrome-signin-team@google.com</owner>
+  <summary>
+    Records how many successive batches of throttled network requests has timed
+    out without the cookie being fresh in between. Recorded when cookies become
+    fresh or on session termination/shutdown if any requests has hit the
+    timeout.
+  </summary>
+</histogram>
+
 <histogram base="true" name="Signin.CookieJar.ChromeAccountRelation"
     enum="AccountRelation" expires_after="never">
 <!-- expires-never: this histogram gives important user information about user
@@ -949,7 +993,7 @@
 </histogram>
 
 <histogram name="Signin.ListFamilyMembersRequest.Latency" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>tju@google.com</owner>
   <owner>chrome-kids-eng@google.com</owner>
   <summary>
@@ -996,7 +1040,7 @@
 </histogram>
 
 <histogram name="Signin.ListFamilyMembersRequest.Status"
-    enum="SupervisedUserProtoFetcherStatus" expires_after="2024-03-03">
+    enum="SupervisedUserProtoFetcherStatus" expires_after="2024-05-05">
   <owner>tju@google.com</owner>
   <owner>chrome-kids-eng@google.com</owner>
   <summary>
@@ -1671,8 +1715,8 @@
   </summary>
 </histogram>
 
-<histogram name="Signin.SyncPromo.{Action}.Count.{AccessPoint}" units="counts"
-    expires_after="2024-03-22">
+<histogram name="Signin.SyncPromo.{Action}.Count.{AccessPoint}"
+    units="bookmarks" expires_after="2024-03-22">
   <owner>triploblastic@chromium.org</owner>
   <owner>chrome-signin-team@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/startup/histograms.xml b/tools/metrics/histograms/metadata/startup/histograms.xml
index 76c62251d..daed0c2 100644
--- a/tools/metrics/histograms/metadata/startup/histograms.xml
+++ b/tools/metrics/histograms/metadata/startup/histograms.xml
@@ -433,7 +433,7 @@
 </histogram>
 
 <histogram name="Startup.Android.GURLEnsureMainDexInitialized" units="ms"
-    expires_after="2024-03-04">
+    expires_after="2024-05-05">
   <owner>mthiesse@chromium.org</owner>
   <owner>yfriedman@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/storage/histograms.xml b/tools/metrics/histograms/metadata/storage/histograms.xml
index d3ab6f2..418ffa8 100644
--- a/tools/metrics/histograms/metadata/storage/histograms.xml
+++ b/tools/metrics/histograms/metadata/storage/histograms.xml
@@ -540,7 +540,7 @@
 </histogram>
 
 <histogram name="Storage.InterestGroup.DBErrors" units="count"
-    expires_after="M123">
+    expires_after="2024-05-05">
   <owner>behamilton@google.com</owner>
   <owner>pauljensen@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/sync/histograms.xml b/tools/metrics/histograms/metadata/sync/histograms.xml
index 6b2a89d0..d31a752 100644
--- a/tools/metrics/histograms/metadata/sync/histograms.xml
+++ b/tools/metrics/histograms/metadata/sync/histograms.xml
@@ -298,7 +298,7 @@
 </histogram>
 
 <histogram name="Sync.CommitResponse{SyncModelType}" enum="SyncerErrorValues"
-    expires_after="2024-03-02">
+    expires_after="2024-05-05">
   <owner>rushans@google.com</owner>
   <owner>treib@chromium.org</owner>
   <component>Services&gt;Sync</component>
@@ -869,7 +869,7 @@
 </histogram>
 
 <histogram name="Sync.ModelTypeConfigurationTime.{StorageType}{SyncModelType}"
-    units="ms" expires_after="2024-03-06">
+    units="ms" expires_after="2024-05-05">
   <owner>rushans@google.com</owner>
   <owner>mastiz@chromium.org</owner>
   <component>Services&gt;Sync</component>
@@ -1370,7 +1370,7 @@
 </histogram>
 
 <histogram name="Sync.SharingMessage.CommitResult"
-    enum="SyncSharingMessageCommitErrorCode" expires_after="2024-03-03">
+    enum="SyncSharingMessageCommitErrorCode" expires_after="2024-05-05">
   <owner>rushans@google.com</owner>
   <owner>treib@chromium.org</owner>
   <component>Services&gt;Sync</component>
@@ -2008,7 +2008,7 @@
 </histogram>
 
 <histogram name="Sync.URLFetchResponse"
-    enum="CombinedHttpResponseAndNetErrorCode" expires_after="2024-03-03">
+    enum="CombinedHttpResponseAndNetErrorCode" expires_after="2024-05-05">
   <owner>mastiz@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <component>Services&gt;Sync</component>
diff --git a/tools/metrics/histograms/metadata/tab/histograms.xml b/tools/metrics/histograms/metadata/tab/histograms.xml
index 3c12dc65..6daeefa0 100644
--- a/tools/metrics/histograms/metadata/tab/histograms.xml
+++ b/tools/metrics/histograms/metadata/tab/histograms.xml
@@ -482,7 +482,7 @@
 </histogram>
 
 <histogram name="TabGroups.SavedTabGroupAge" units="minutes"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>dljames@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
   <summary>
@@ -493,7 +493,7 @@
 </histogram>
 
 <histogram name="TabGroups.SavedTabGroupCount" units="groups"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>dljames@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
   <summary>
@@ -538,7 +538,7 @@
 </histogram>
 
 <histogram name="TabGroups.SavedTabGroupTimeSinceModification" units="minutes"
-    expires_after="2023-12-27">
+    expires_after="2024-05-05">
   <owner>dljames@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
   <summary>
@@ -1281,7 +1281,7 @@
 </histogram>
 
 <histogram name="Tabs.PageLoad.TimeSinceActive" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>emshack@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
   <summary>
@@ -1291,7 +1291,7 @@
 </histogram>
 
 <histogram name="Tabs.PageLoad.TimeSinceCreated" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>emshack@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/translate/histograms.xml b/tools/metrics/histograms/metadata/translate/histograms.xml
index 9a3ca353..988de6c 100644
--- a/tools/metrics/histograms/metadata/translate/histograms.xml
+++ b/tools/metrics/histograms/metadata/translate/histograms.xml
@@ -686,19 +686,6 @@
   </summary>
 </histogram>
 
-<histogram name="Translate.UnsupportedLanguageAtInitiation" enum="LanguageName"
-    expires_after="M81">
-  <owner>megjablon@google.com</owner>
-  <owner>chrome-language@google.com</owner>
-  <summary>
-    Logs an unsupported source language detected during initiation of the
-    Translate feature. This is reported when the language detector successfully
-    detects the language of the webpage, but the language is not supported by
-    the translation server because it is too minor. This metric allows us to
-    assess how important the unsupported language is for Google translate.
-  </summary>
-</histogram>
-
 <histogram name="TranslateModelService.LanguageDetectionModel.WasLoaded"
     enum="BooleanLoaded" expires_after="2024-12-10">
   <owner>mcrouse@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/uma/histograms.xml b/tools/metrics/histograms/metadata/uma/histograms.xml
index 6fd5f40..4b7548f 100644
--- a/tools/metrics/histograms/metadata/uma/histograms.xml
+++ b/tools/metrics/histograms/metadata/uma/histograms.xml
@@ -57,7 +57,7 @@
 </histogram>
 
 <histogram name="Histogram.MismatchedConstructionArguments"
-    enum="HistogramNameHash" expires_after="2024-03-03">
+    enum="HistogramNameHash" expires_after="2024-05-05">
   <owner>asvitkine@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
   <summary>
@@ -271,7 +271,7 @@
 </histogram>
 
 <histogram name="UMA.EntropySourceType" enum="UmaEntropySourceType"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>asvitkine@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
   <summary>
@@ -281,7 +281,7 @@
 </histogram>
 
 <histogram name="UMA.ExternalExperiment.GroupCount" units="groups"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>asvitkine@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
   <summary>
@@ -293,7 +293,7 @@
 </histogram>
 
 <histogram name="UMA.FileMetricsProvider.AccessResult"
-    enum="FileMetricsProviderAccessResult" expires_after="2024-03-03">
+    enum="FileMetricsProviderAccessResult" expires_after="2024-05-05">
   <owner>asvitkine@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
   <summary>
@@ -731,7 +731,7 @@
 </histogram>
 
 <histogram name="UMA.ProtoCompressionRatio" units="%"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>asvitkine@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
   <summary>
@@ -815,7 +815,7 @@
 </histogram>
 
 <histogram name="UMA.StatisticsRecorder.LockWaitTime" units="ms"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>asvitkine@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
   <summary>
@@ -956,7 +956,7 @@
 </histogram>
 
 <histogram name="UMA.TruncatedEvents.UserAction" units="events"
-    expires_after="2024-04-28">
+    expires_after="2024-05-05">
   <owner>rkaplow@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/update_engine/histograms.xml b/tools/metrics/histograms/metadata/update_engine/histograms.xml
index 56a1396..066cadee 100644
--- a/tools/metrics/histograms/metadata/update_engine/histograms.xml
+++ b/tools/metrics/histograms/metadata/update_engine/histograms.xml
@@ -23,7 +23,7 @@
 <histograms>
 
 <histogram name="UpdateEngine.Attempt.ConnectionType"
-    enum="UpdateEngineConnectionType" expires_after="2024-01-01">
+    enum="UpdateEngineConnectionType" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -39,7 +39,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Attempt.DownloadErrorCode"
-    enum="UpdateEngineDownloadErrorCode" expires_after="2024-03-03">
+    enum="UpdateEngineDownloadErrorCode" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -54,7 +54,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Attempt.DownloadSource"
-    enum="UpdateEngineDownloadSource" expires_after="2024-01-01">
+    enum="UpdateEngineDownloadSource" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -68,7 +68,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Attempt.DurationMinutes" units="minutes"
-    expires_after="2024-04-28">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -82,7 +82,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Attempt.DurationUptimeMinutes" units="minutes"
-    expires_after="2024-01-01">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -96,7 +96,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Attempt.InternalErrorCode"
-    enum="UpdateEngineErrorCode" expires_after="2024-03-03">
+    enum="UpdateEngineErrorCode" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -110,7 +110,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Attempt.Number" units="count"
-    expires_after="2024-03-03">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -124,7 +124,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Attempt.PayloadBytesDownloadedMiB" units="MiB"
-    expires_after="2024-03-03">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -137,7 +137,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Attempt.PayloadDownloadSpeedKBps" units="KBps"
-    expires_after="2024-01-01">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -152,7 +152,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Attempt.PayloadSizeMiB" units="MiB"
-    expires_after="2023-12-10">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -165,7 +165,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Attempt.PayloadType"
-    enum="UpdateEnginePayloadFormat" expires_after="2024-01-01">
+    enum="UpdateEnginePayloadFormat" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -181,7 +181,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Attempt.Result" enum="UpdateEngineAttemptResult"
-    expires_after="2024-03-03">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -194,7 +194,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Attempt.TimeSinceLastAttemptMinutes"
-    units="minutes" expires_after="2023-12-10">
+    units="minutes" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -209,7 +209,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Attempt.TimeSinceLastAttemptUptimeMinutes"
-    units="minutes" expires_after="2024-01-01">
+    units="minutes" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -224,7 +224,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.CertificateCheck.Download"
-    enum="UpdateEngineCertificateCheckStatus" expires_after="2024-01-01">
+    enum="UpdateEngineCertificateCheckStatus" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -239,7 +239,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.CertificateCheck.UpdateCheck"
-    enum="UpdateEngineCertificateCheckStatus" expires_after="2024-03-03">
+    enum="UpdateEngineCertificateCheckStatus" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -253,7 +253,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Check.DownloadErrorCode"
-    enum="UpdateEngineDownloadErrorCode" expires_after="2024-01-01">
+    enum="UpdateEngineDownloadErrorCode" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -268,7 +268,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Check.Reaction" enum="UpdateEngineCheckReaction"
-    expires_after="2024-03-03">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -284,7 +284,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Check.Result" enum="UpdateEngineCheckResult"
-    expires_after="2024-03-03">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -299,7 +299,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Check.RollbackTargetVersion"
-    enum="UpdateEngineChromeOsVersionPrefix" expires_after="2024-04-28">
+    enum="UpdateEngineChromeOsVersionPrefix" expires_after="2024-04-01">
   <owner>mpolzer@google.com</owner>
   <owner>crisguerrero@chromium.org</owner>
   <owner>chromeos-commercial-remote-management@google.com</owner>
@@ -319,7 +319,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Check.TargetVersion"
-    enum="UpdateEngineChromeOsVersionPrefix" expires_after="2024-04-28">
+    enum="UpdateEngineChromeOsVersionPrefix" expires_after="2024-04-01">
   <owner>mpolzer@google.com</owner>
   <owner>chromeos-commercial-remote-management@google.com</owner>
   <summary>
@@ -337,7 +337,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Check.TimeSinceLastCheckMinutes" units="minutes"
-    expires_after="2024-01-01">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -351,7 +351,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Check.TimeSinceLastCheckUptimeMinutes"
-    units="minutes" expires_after="2024-01-01">
+    units="minutes" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -365,7 +365,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.ConsecutiveUpdate.Count" units="updates"
-    expires_after="2024-03-03">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -378,7 +378,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.ConsecutiveUpdate.Failed" enum="BooleanHit"
-    expires_after="2024-01-01">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -391,7 +391,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.ConsumerAutoUpdate" enum="BooleanOptedOut"
-    expires_after="2024-03-03">
+    expires_after="2024-04-01">
   <owner>yuanpengni@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -403,7 +403,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Daily.OSAgeDays" units="days"
-    expires_after="2024-02-11">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -488,7 +488,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.FailedUpdateCount" units="count"
-    expires_after="2024-03-03">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -503,7 +503,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.InstallDateProvisioningSource"
-    enum="UpdateEngineInstallDateProvisioningSource" expires_after="2024-01-01">
+    enum="UpdateEngineInstallDateProvisioningSource" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -568,7 +568,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.Rollback.Result" enum="BooleanSuccess"
-    expires_after="2024-03-31">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -581,7 +581,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.SuccessfulUpdate.AttemptCount" units="count"
-    expires_after="2024-03-03">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -594,7 +594,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.SuccessfulUpdate.BytesDownloadedMiB" units="MiB"
-    expires_after="2024-01-01">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -608,7 +608,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.SuccessfulUpdate.BytesDownloadedMiBHttpPeer"
-    units="MiB" expires_after="2024-01-01">
+    units="MiB" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -622,7 +622,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.SuccessfulUpdate.BytesDownloadedMiBHttpServer"
-    units="MiB" expires_after="2024-01-01">
+    units="MiB" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -636,7 +636,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.SuccessfulUpdate.BytesDownloadedMiBHttpsServer"
-    units="MiB" expires_after="2024-01-01">
+    units="MiB" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -650,7 +650,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.SuccessfulUpdate.DownloadOverheadPercentage"
-    units="%" expires_after="2024-01-01">
+    units="%" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -663,7 +663,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.SuccessfulUpdate.DownloadSourcesUsed"
-    enum="UpdateEngineDownloadSources" expires_after="2024-01-01">
+    enum="UpdateEngineDownloadSources" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -676,37 +676,8 @@
   </summary>
 </histogram>
 
-<histogram
-    name="UpdateEngine.SuccessfulUpdate.DurationFromSeenDays.NoTimeRestriction"
-    units="days" expires_after="2023-07-16">
-  <owner>snijhara@google.com</owner>
-  <owner>managed-platforms@google.com</owner>
-  <summary>
-    The total number of days from when an update is first seen to when an update
-    is finished downloading (but before rebooting). This metric is recorded on
-    enterprise-enrolled devices that do not have the
-    DeviceAutoUpdateTimeRestrictions policy enabled.
-
-    This metric is specific to Chrome OS.
-  </summary>
-</histogram>
-
-<histogram
-    name="UpdateEngine.SuccessfulUpdate.DurationFromSeenDays.TimeRestricted"
-    units="days" expires_after="2023-01-01">
-  <owner>snijhara@google.com</owner>
-  <owner>managed-platforms@google.com</owner>
-  <summary>
-    The total number of days from when an update is first seen to when an update
-    is finished downloading (but before rebooting). This metric is recorded on
-    devices that have the DeviceAutoUpdateTimeRestrictions policy enabled.
-
-    This metric is specific to Chrome OS.
-  </summary>
-</histogram>
-
 <histogram name="UpdateEngine.SuccessfulUpdate.PayloadSizeMiB" units="MiB"
-    expires_after="2024-01-01">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -719,7 +690,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.SuccessfulUpdate.PayloadType"
-    enum="UpdateEnginePayloadFormat" expires_after="2024-03-03">
+    enum="UpdateEnginePayloadFormat" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -733,7 +704,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.SuccessfulUpdate.RebootCount" units="count"
-    expires_after="2024-01-01">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -746,7 +717,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.SuccessfulUpdate.TotalDurationMinutes"
-    units="minutes" expires_after="2024-03-03">
+    units="minutes" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -761,7 +732,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.SuccessfulUpdate.TotalDurationUptimeMinutes"
-    units="minutes" expires_after="2024-03-03">
+    units="minutes" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -776,7 +747,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.SuccessfulUpdate.UpdatesAbandonedCount"
-    units="count" expires_after="2024-01-01">
+    units="count" expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -790,7 +761,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.SuccessfulUpdate.UrlSwitchCount" units="count"
-    expires_after="2024-01-01">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -804,7 +775,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.TimeToRebootMinutes" units="minutes"
-    expires_after="2024-03-03">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
@@ -820,7 +791,7 @@
 </histogram>
 
 <histogram name="UpdateEngine.UpdateInvalidated" enum="BooleanSuccess"
-    expires_after="2024-01-01">
+    expires_after="2024-04-01">
   <owner>kimjae@chromium.org</owner>
   <owner>chromeos-core-services@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/variations/histograms.xml b/tools/metrics/histograms/metadata/variations/histograms.xml
index a346692..ab8a8b3 100644
--- a/tools/metrics/histograms/metadata/variations/histograms.xml
+++ b/tools/metrics/histograms/metadata/variations/histograms.xml
@@ -47,7 +47,7 @@
 </histogram>
 
 <histogram name="Variations.AppSeedFreshness" units="minutes"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>ntfschr@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
@@ -702,7 +702,7 @@
 </histogram>
 
 <histogram name="Variations.WebViewDownloadJobInterval" units="minutes"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>ntfschr@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
@@ -713,7 +713,7 @@
 </histogram>
 
 <histogram name="Variations.WebViewDownloadJobQueueTime" units="minutes"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>ntfschr@chromium.org</owner>
   <owner>src/android_webview/OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/web_apk/histograms.xml b/tools/metrics/histograms/metadata/web_apk/histograms.xml
index c52c62e1..5d3fce8d6 100644
--- a/tools/metrics/histograms/metadata/web_apk/histograms.xml
+++ b/tools/metrics/histograms/metadata/web_apk/histograms.xml
@@ -164,7 +164,7 @@
 </histogram>
 
 <histogram name="WebApk.Install.RequestTokenDurationV2" units="ms"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>hartmanng@chromium.org</owner>
   <owner>rayankans@chromium.org</owner>
   <owner>src/chrome/android/webapk/OWNERS</owner>
@@ -178,7 +178,7 @@
 </histogram>
 
 <histogram name="WebApk.Install.UserTheme" enum="WebApkUserTheme"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>johnwes@google.com</owner>
   <owner>src/chrome/android/webapk/OWNERS</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/web_rtc/histograms.xml b/tools/metrics/histograms/metadata/web_rtc/histograms.xml
index ad530ac..ea2942d 100644
--- a/tools/metrics/histograms/metadata/web_rtc/histograms.xml
+++ b/tools/metrics/histograms/metadata/web_rtc/histograms.xml
@@ -104,7 +104,7 @@
 </variants>
 
 <histogram name="WebRTC.Audio.Agc.InputClippingRate" units="%"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>silen@chromium.org</owner>
   <owner>alessiob@chromium.org</owner>
   <owner>webrtc-audio-uma@google.com</owner>
@@ -115,7 +115,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.Agc2.DigitalGainApplied" units="dB"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>alessiob@chromium.org</owner>
   <owner>silen@chromium.org</owner>
   <owner>webrtc-audio-uma@google.com</owner>
@@ -141,7 +141,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.Agc2.FixedDigitalGainCurveRegion.{Region}"
-    units="seconds" expires_after="2024-03-03">
+    units="seconds" expires_after="2024-05-05">
   <owner>alessiob@chromium.org</owner>
   <owner>silen@chromium.org</owner>
   <owner>webrtc-audio-uma@google.com</owner>
@@ -173,7 +173,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.Apm.RecommendedInputVolume.OnChangeToMatchTarget"
-    units="volume" expires_after="2024-03-03">
+    units="volume" expires_after="2024-05-05">
   <owner>silen@chromium.org</owner>
   <owner>alessiob@chromium.org</owner>
   <owner>webrtc-audio-uma@google.com</owner>
@@ -185,7 +185,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.Apm.{InputVolumeType}.OnChange" units="volume"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>silen@chromium.org</owner>
   <owner>alessiob@chromium.org</owner>
   <owner>webrtc-audio-uma@google.com</owner>
@@ -200,7 +200,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.Apm.{InputVolumeType}.{Metric}Average"
-    units="volume" expires_after="2024-03-03">
+    units="volume" expires_after="2024-05-05">
   <owner>silen@chromium.org</owner>
   <owner>alessiob@chromium.org</owner>
   <owner>webrtc-audio-uma@google.com</owner>
@@ -221,7 +221,7 @@
 </histogram>
 
 <histogram name="WebRTC.Audio.Apm.{InputVolumeType}.{Metric}Rate"
-    units="changes/minute" expires_after="2024-03-03">
+    units="changes/minute" expires_after="2024-05-05">
   <owner>silen@chromium.org</owner>
   <owner>alessiob@chromium.org</owner>
   <owner>webrtc-audio-uma@google.com</owner>
@@ -1168,7 +1168,7 @@
 </histogram>
 
 <histogram name="WebRTC.PeerConnection.AddIceCandidate"
-    enum="AddIceCandidateResult" expires_after="2024-03-03">
+    enum="AddIceCandidateResult" expires_after="2024-05-05">
   <owner>hta@chromium.org</owner>
   <owner>webrtc-dev@chromium.org</owner>
   <summary>
@@ -1178,7 +1178,7 @@
 </histogram>
 
 <histogram name="WebRTC.PeerConnection.BundlePolicy"
-    enum="PeerConnectionBundlePolicy" expires_after="2024-03-03">
+    enum="PeerConnectionBundlePolicy" expires_after="2024-05-05">
   <owner>hta@chromium.org</owner>
   <owner>webrtc-dev@chromium.org</owner>
   <summary>
@@ -1192,7 +1192,7 @@
 </histogram>
 
 <histogram name="WebRTC.PeerConnection.BundleUsage"
-    enum="PeerConnectionBundleUsage" expires_after="2024-03-03">
+    enum="PeerConnectionBundleUsage" expires_after="2024-05-05">
   <owner>hta@chromium.org</owner>
   <owner>webrtc-dev@chromium.org</owner>
   <summary>
@@ -1244,7 +1244,7 @@
 </histogram>
 
 <histogram name="WebRTC.PeerConnection.ConnectionState"
-    enum="IceConnectionStates" expires_after="2024-03-03">
+    enum="IceConnectionStates" expires_after="2024-05-05">
   <owner>hta@chromium.org</owner>
   <owner>webrtc-dev@chromium.org</owner>
   <summary>
@@ -1977,7 +1977,7 @@
 </histogram>
 
 <histogram name="WebRTC.UserMediaRequest.Result2"
-    enum="MediaStreamRequestResult2" expires_after="2024-03-03">
+    enum="MediaStreamRequestResult2" expires_after="2024-05-05">
   <owner>toprice@chromium.org</owner>
   <owner>agpalak@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/webapps/histograms.xml b/tools/metrics/histograms/metadata/webapps/histograms.xml
index 882d81e..74c3df1 100644
--- a/tools/metrics/histograms/metadata/webapps/histograms.xml
+++ b/tools/metrics/histograms/metadata/webapps/histograms.xml
@@ -741,7 +741,7 @@
 </histogram>
 
 <histogram name="Webapp.Install.DisplayMode2" enum="WebAppDisplayMode"
-    expires_after="2024-03-03">
+    expires_after="2024-05-05">
   <owner>peter@chromium.org</owner>
   <owner>yfriedman@chromium.org</owner>
   <summary>
@@ -1330,7 +1330,7 @@
 
 <histogram
     name="WebApp.Preinstalled.WindowExperiment.{UserGroup}.{DisplayModeChange}"
-    enum="DefaultAppName" expires_after="2024-03-03">
+    enum="DefaultAppName" expires_after="2024-05-05">
   <owner>glenrob@chromium.org</owner>
   <owner>desktop-pwas-team@google.com</owner>
   <summary>
@@ -1351,7 +1351,7 @@
 
 <histogram
     name="WebApp.Preinstalled.WindowExperiment.{UserGroup}.{LinkCapturingChange}"
-    enum="DefaultAppName" expires_after="2024-03-03">
+    enum="DefaultAppName" expires_after="2024-05-05">
   <owner>glenrob@chromium.org</owner>
   <owner>desktop-pwas-team@google.com</owner>
   <summary>
@@ -1422,7 +1422,7 @@
 </histogram>
 
 <histogram name="WebApp.RunOnOsLogin.Registration.Result" enum="BooleanSuccess"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>dibyapal@chromium.org</owner>
   <owner>desktop-pwas-team@google.com</owner>
   <summary>
@@ -1435,7 +1435,7 @@
 </histogram>
 
 <histogram name="WebApp.RunOnOsLogin.Unregistration.Result"
-    enum="BooleanSuccess" expires_after="2024-03-01">
+    enum="BooleanSuccess" expires_after="2024-05-05">
   <owner>dibyapal@chromium.org</owner>
   <owner>desktop-pwas-team@google.com</owner>
   <summary>
@@ -1623,7 +1623,7 @@
 </histogram>
 
 <histogram name="Webapp.UninstallDialogAction"
-    enum="WebappUninstallDialogAction" expires_after="2024-03-03">
+    enum="WebappUninstallDialogAction" expires_after="2024-05-05">
   <owner>benwells@chromium.org</owner>
   <owner>dominickn@chromium.org</owner>
   <owner>desktop-pwas-team@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/webauthn/histograms.xml b/tools/metrics/histograms/metadata/webauthn/histograms.xml
index f624937..554b98a 100644
--- a/tools/metrics/histograms/metadata/webauthn/histograms.xml
+++ b/tools/metrics/histograms/metadata/webauthn/histograms.xml
@@ -33,7 +33,7 @@
 </histogram>
 
 <histogram name="WebAuthentication.Android.CredManCreateRequest"
-    enum="CredManCreateRequestEnum" expires_after="2024-01-01">
+    enum="CredManCreateRequestEnum" expires_after="2024-05-05">
   <owner>derinel@google.com</owner>
   <owner>kenrb@chromium.org</owner>
   <summary>
@@ -53,7 +53,7 @@
 </histogram>
 
 <histogram name="WebAuthentication.Android.CredManPrepareRequest"
-    enum="CredManPrepareRequestEnum" expires_after="2024-01-01">
+    enum="CredManPrepareRequestEnum" expires_after="2024-05-05">
   <owner>derinel@google.com</owner>
   <owner>kenrb@chromium.org</owner>
   <summary>
@@ -62,7 +62,7 @@
 </histogram>
 
 <histogram name="WebAuthentication.Android.CredManPrepareRequestDuration"
-    units="ms" expires_after="2024-01-01">
+    units="ms" expires_after="2024-05-05">
   <owner>derinel@google.com</owner>
   <owner>kenrb@chromium.org</owner>
   <summary>
@@ -100,14 +100,14 @@
 </histogram>
 
 <histogram name="WebAuthentication.CableV2.MobileResult"
-    enum="WebAuthenticationCableV2MobileResult" expires_after="2024-03-01">
+    enum="WebAuthenticationCableV2MobileResult" expires_after="2024-05-05">
   <owner>agl@chromium.org</owner>
   <owner>martinkr@google.com</owner>
   <summary>Records the outcome of caBLEv2 transactions.</summary>
 </histogram>
 
 <histogram name="WebAuthentication.CableV2.PrelinkDataAgeDays" units="days"
-    expires_after="2024-03-01">
+    expires_after="2024-05-05">
   <owner>agl@chromium.org</owner>
   <owner>nsatragno@google.com</owner>
   <summary>
diff --git a/ui/android/delegated_frame_host_android.cc b/ui/android/delegated_frame_host_android.cc
index 9bad8f2..101e221a 100644
--- a/ui/android/delegated_frame_host_android.cc
+++ b/ui/android/delegated_frame_host_android.cc
@@ -251,11 +251,12 @@
     return;
   }
 
-  // If we have a surface from before a navigation and we are not in BFCache,
-  // evict it as well.
-  if (!bfcache_fallback_.is_valid() &&
-      pre_navigation_local_surface_id_.is_valid() &&
+  // If we have a surface from before a navigation, evict it as well.
+  if (pre_navigation_local_surface_id_.is_valid() &&
       !first_local_surface_id_after_navigation_.is_valid()) {
+    // If we have a valid `pre_navigation_local_surface_id_`, we must not be in
+    // BFCache.
+    CHECK(!bfcache_fallback_.is_valid());
     EvictDelegatedFrame(frame_evictor_->CollectSurfaceIdsForEviction());
     content_layer_->SetBackgroundColor(SkColors::kTransparent);
   }
@@ -513,13 +514,15 @@
 
 void DelegatedFrameHostAndroid::DidEnterBackForwardCache() {
   if (local_surface_id_.is_valid()) {
-    // Resize while hidden (`EmbedSurface` called after
-    // `DidNavigateMainFramePreCommit` and before `DidEnterBackForwardCache`).
+    // `EmbedSurface` can be called after `DidNavigateMainFramePreCommit` and
+    // before `DidEnterBackForwardCache`. This can happen if there is an
+    // on-going Hi-DPI capture on the old frame (see
+    // `WebContentsFrameTracker::RenderFrameHostChanged()`).
     //
-    // The `EmbedSurface` for the resize will invalidate
-    // `pre_navigation_local_surface_id_`. In this case we shouldn't restore the
-    // `local_surface_id_` because the surface with a different size should have
-    // a new ID.
+    // The `EmbedSurface` will invalidate `pre_navigation_local_surface_id_`. In
+    // this case we shouldn't restore the `local_surface_id_` nor
+    // `bfcache_fallback_`because the surface should embed the latest
+    // `local_surface_id_`.
     CHECK(!pre_navigation_local_surface_id_.is_valid());
     CHECK(!bfcache_fallback_.is_valid());
   } else {
diff --git a/ui/android/view_android.cc b/ui/android/view_android.cc
index 2ec346e..9c3ffc1 100644
--- a/ui/android/view_android.cc
+++ b/ui/android/view_android.cc
@@ -740,4 +740,14 @@
   bounds_.SetRect(x, y, width, height);
 }
 
+size_t ViewAndroid::GetChildrenCountForTesting() const {
+  return children_.size();
+}
+
+const ViewAndroid* ViewAndroid::GetTopMostChildForTesting() const {
+  // The top-most refers to the back element of the children. This is mirroring
+  // the children ordering of the cc Layer tree.
+  return children_.back();
+}
+
 }  // namespace ui
diff --git a/ui/android/view_android.h b/ui/android/view_android.h
index e99aff2..843b771e6 100644
--- a/ui/android/view_android.h
+++ b/ui/android/view_android.h
@@ -239,6 +239,10 @@
 
   EventForwarder* event_forwarder() { return event_forwarder_.get(); }
 
+  size_t GetChildrenCountForTesting() const;
+
+  const ViewAndroid* GetTopMostChildForTesting() const;
+
  protected:
   void RemoveAllChildren(bool attached_to_window);
 
diff --git a/ui/base/resource/resource_handle.h b/ui/base/resource/resource_handle.h
index 4b6ea2c..fd71ca5 100644
--- a/ui/base/resource/resource_handle.h
+++ b/ui/base/resource/resource_handle.h
@@ -10,6 +10,7 @@
 #include <vector>
 
 #include "base/component_export.h"
+#include "base/dcheck_is_on.h"
 #include "base/strings/string_piece.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/resource/resource_scale_factor.h"
diff --git a/ui/compositor/debug_utils.cc b/ui/compositor/debug_utils.cc
index 543a20ae8..0f833f54 100644
--- a/ui/compositor/debug_utils.cc
+++ b/ui/compositor/debug_utils.cc
@@ -27,7 +27,8 @@
 void PrintLayerHierarchyImp(const Layer* layer,
                             int indent,
                             const gfx::Point& mouse_location,
-                            std::ostringstream* out) {
+                            std::ostringstream* out,
+                            DebugLayerChildCallback child_cb) {
   std::string indent_str(indent, ' ');
 
   gfx::Point transformed_mouse_location = layer->transform()
@@ -120,8 +121,12 @@
 
   *out << '\n';
 
-  for (ui::Layer* child : layer->children())
-    PrintLayerHierarchyImp(child, indent + 3, mouse_location_in_layer, out);
+  std::vector<ui::Layer*> children =
+      child_cb ? child_cb.Run(layer) : layer->children();
+  for (ui::Layer* child : children) {
+    PrintLayerHierarchyImp(child, indent + 3, mouse_location_in_layer, out,
+                           child_cb);
+  }
 }
 
 }  // namespace
@@ -135,9 +140,10 @@
 
 void PrintLayerHierarchy(const Layer* layer,
                          const gfx::Point& mouse_location,
-                         std::ostringstream* out) {
+                         std::ostringstream* out,
+                         DebugLayerChildCallback child_cb) {
   *out << "Layer hierarchy:\n";
-  PrintLayerHierarchyImp(layer, 0, mouse_location, out);
+  PrintLayerHierarchyImp(layer, 0, mouse_location, out, child_cb);
 }
 
 }  // namespace ui
diff --git a/ui/compositor/debug_utils.h b/ui/compositor/debug_utils.h
index 8c4ac925..4080dfab 100644
--- a/ui/compositor/debug_utils.h
+++ b/ui/compositor/debug_utils.h
@@ -6,7 +6,9 @@
 #define UI_COMPOSITOR_DEBUG_UTILS_H_
 
 #include <sstream>
+#include <vector>
 
+#include "base/functional/callback.h"
 #include "ui/compositor/compositor_export.h"
 
 namespace gfx {
@@ -17,15 +19,20 @@
 
 class Layer;
 
+using DebugLayerChildCallback =
+    base::RepeatingCallback<std::vector<Layer*>(const Layer*)>;
+
 // Log the layer hierarchy. Mark layers which contain |mouse_location| with '*'.
 COMPOSITOR_EXPORT void PrintLayerHierarchy(const Layer* layer,
                                            const gfx::Point& mouse_location);
 
 // Print the layer hierarchy to |out|. Mark layers which contain
 // |mouse_location| with '*'.
-COMPOSITOR_EXPORT void PrintLayerHierarchy(const Layer* layer,
-                                           const gfx::Point& mouse_location,
-                                           std::ostringstream* out);
+COMPOSITOR_EXPORT void PrintLayerHierarchy(
+    const Layer* layer,
+    const gfx::Point& mouse_location,
+    std::ostringstream* out,
+    DebugLayerChildCallback child_cb = DebugLayerChildCallback());
 
 }  // namespace ui
 
diff --git a/ui/file_manager/BUILD.gn b/ui/file_manager/BUILD.gn
index 3901b00..ae8d0ef 100644
--- a/ui/file_manager/BUILD.gn
+++ b/ui/file_manager/BUILD.gn
@@ -196,13 +196,7 @@
 
   manifest_excludes = [ "file_manager/externs/file_manager_private.js" ]
 
-  definitions = [
-    "//tools/typescript/definitions/chrome_event.d.ts",
-    "//tools/typescript/definitions/chrome_test.d.ts",
-    "//tools/typescript/definitions/metrics_private.d.ts",
-    "//tools/typescript/definitions/runtime.d.ts",
-    "//tools/typescript/definitions/tabs.d.ts",
-  ]
+  definitions = other_dts_files
   foreach(_file, generate_definitions_js_files) {
     definitions +=
         [ "$target_gen_dir/" + string_replace(_file, ".js", ".d.ts") ]
@@ -255,7 +249,7 @@
                     target_gen_dir),
   ]
 
-  definitions = []
+  definitions = other_dts_files
   foreach(_file, generate_definitions_js_files) {
     definitions +=
         [ "$target_gen_dir/" + string_replace(_file, ".js", ".d.ts") ]
diff --git a/ui/file_manager/file_manager/background/js/volume_info_impl.ts b/ui/file_manager/file_manager/background/js/volume_info_impl.ts
index 03360b60..5627520 100644
--- a/ui/file_manager/file_manager/background/js/volume_info_impl.ts
+++ b/ui/file_manager/file_manager/background/js/volume_info_impl.ts
@@ -62,7 +62,7 @@
    */
   constructor(
       private volumeType_: VolumeManagerCommon.VolumeType,
-      private volumeId_: string, private fileSystem_: FileSystem,
+      private volumeId_: string, private fileSystem_: FileSystem|null,
       // Note: This represents if the mounting of the volume is successfully
       // done or not. (If error is empty string, the mount is successfully
       // done).
@@ -114,7 +114,8 @@
   }
 
   get fileSystem(): FileSystem {
-    return this.fileSystem_;
+    // TODO(b/309054429): fileSystem could be null, handle it gracefully.
+    return this.fileSystem_!;
   }
 
   /** Display root path. It is null before finishing to resolve the entry. */
@@ -267,6 +268,10 @@
    * The return value will resolve once this operation is complete.
    */
   private resolveSharedDrivesRoot_(): Promise<void> {
+    if (!this.fileSystem_) {
+      return Promise.reject(this.error);
+    }
+
     return VolumeInfoImpl
         .resolveFileSystemUrl_(
             this.fileSystem_.root.toURL() +
@@ -292,6 +297,10 @@
    * The return value will resolve once this operation is complete.
    */
   private resolveComputersRoot_(): Promise<void> {
+    if (!this.fileSystem_) {
+      return Promise.reject(this.error);
+    }
+
     return VolumeInfoImpl
         .resolveFileSystemUrl_(
             this.fileSystem_.root.toURL() +
diff --git a/ui/file_manager/file_manager/background/js/volume_manager_impl.ts b/ui/file_manager/file_manager/background/js/volume_manager_impl.ts
index 46446fa..b5821203 100644
--- a/ui/file_manager/file_manager/background/js/volume_manager_impl.ts
+++ b/ui/file_manager/file_manager/background/js/volume_manager_impl.ts
@@ -8,17 +8,151 @@
 
 import {promisify} from '../../common/js/api.js';
 import {getRootType, isComputersRoot, isFakeEntry, isSameEntry, isSameFileSystem, isTeamDriveRoot} from '../../common/js/entry_utils.js';
+import {str} from '../../common/js/translations.js';
+import {timeoutPromise} from '../../common/js/util.js';
 import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js';
 import {EntryLocation} from '../../externs/entry_location.js';
 import {FilesAppDirEntry, FilesAppEntry} from '../../externs/files_app_entry_interfaces.js';
 import type {VolumeInfo} from '../../externs/volume_info.js';
 import {VolumeManager} from '../../externs/volume_manager.js';
-import {removeVolume} from '../../state/ducks/volumes.js';
+import {addVolume, removeVolume} from '../../state/ducks/volumes.js';
 import {getStore} from '../../state/store.js';
 
 import {EntryLocationImpl} from './entry_location_impl.js';
+import {VolumeInfoImpl} from './volume_info_impl.js';
 import {VolumeInfoListImpl} from './volume_info_list_impl.js';
-import {volumeManagerUtil} from './volume_manager_util.js';
+
+
+/**
+ * Time in milliseconds that we wait a response for general volume operations
+ * such as mount, unmount, and requestFileSystem. If no response on
+ * mount/unmount received the request supposed failed.
+ */
+const TIMEOUT = 15 * 60 * 1000;
+
+const TIMEOUT_STR_REQUEST_FILE_SYSTEM = 'timeout(requestFileSystem)';
+
+/**
+ * Logs a warning message if the given error is not in
+ * VolumeManagerCommon.VolumeError.
+ *
+ * @param error Status string usually received from APIs.
+ */
+function validateError(error: string) {
+  const found = Object.values(VolumeManagerCommon.VolumeError)
+                    .find(value => value === error);
+  if (found) {
+    return;
+  }
+
+  console.warn(`Invalid mount error: ${error}`);
+}
+
+/**
+ * Builds the VolumeInfo data from chrome.fileManagerPrivate.VolumeMetadata.
+ * @param volumeMetadata Metadata instance for the volume.
+ * @return Promise settled with the VolumeInfo instance.
+ */
+export async function createVolumeInfo(
+    volumeMetadata: chrome.fileManagerPrivate.VolumeMetadata):
+    Promise<VolumeInfo> {
+  let localizedLabel: string;
+  switch (volumeMetadata.volumeType) {
+    case VolumeManagerCommon.VolumeType.DOWNLOADS:
+      localizedLabel = str('MY_FILES_ROOT_LABEL');
+      break;
+    case VolumeManagerCommon.VolumeType.DRIVE:
+      localizedLabel = str('DRIVE_DIRECTORY_LABEL');
+      break;
+    case VolumeManagerCommon.VolumeType.MEDIA_VIEW:
+      switch (VolumeManagerCommon.getMediaViewRootTypeFromVolumeId(
+          volumeMetadata.volumeId)) {
+        case VolumeManagerCommon.MediaViewRootType.IMAGES:
+          localizedLabel = str('MEDIA_VIEW_IMAGES_ROOT_LABEL');
+          break;
+        case VolumeManagerCommon.MediaViewRootType.VIDEOS:
+          localizedLabel = str('MEDIA_VIEW_VIDEOS_ROOT_LABEL');
+          break;
+        case VolumeManagerCommon.MediaViewRootType.AUDIO:
+          localizedLabel = str('MEDIA_VIEW_AUDIO_ROOT_LABEL');
+          break;
+      }
+      break;
+    case VolumeManagerCommon.VolumeType.CROSTINI:
+      localizedLabel = str('LINUX_FILES_ROOT_LABEL');
+      break;
+    case VolumeManagerCommon.VolumeType.ANDROID_FILES:
+      localizedLabel = str('ANDROID_FILES_ROOT_LABEL');
+      break;
+    default:
+      // TODO(mtomasz): Calculate volumeLabel for all types of volumes in the
+      // C++ layer.
+      localizedLabel = volumeMetadata.volumeLabel ||
+          volumeMetadata.volumeId.split(':', 2)[1]!;
+      break;
+  }
+
+  console.debug(`Getting file system '${volumeMetadata.volumeId}'`);
+  return timeoutPromise(
+             new Promise<DirectoryEntry>((resolve, reject) => {
+               chrome.fileManagerPrivate.getVolumeRoot(
+                   {
+                     volumeId: volumeMetadata.volumeId,
+                     writable: !volumeMetadata.isReadOnly,
+                   },
+                   (rootDirectoryEntry: DirectoryEntry) => {
+                     if (chrome.runtime.lastError) {
+                       reject(chrome.runtime.lastError.message);
+                     } else {
+                       resolve(rootDirectoryEntry);
+                     }
+                   });
+             }),
+             TIMEOUT,
+             TIMEOUT_STR_REQUEST_FILE_SYSTEM + ': ' + volumeMetadata.volumeId)
+      .then(rootDirectoryEntry => {
+        console.debug(`Got file system '${volumeMetadata.volumeId}'`);
+        return new VolumeInfoImpl(
+            volumeMetadata.volumeType, volumeMetadata.volumeId,
+            rootDirectoryEntry.filesystem, volumeMetadata.mountCondition,
+            volumeMetadata.deviceType, volumeMetadata.devicePath,
+            volumeMetadata.isReadOnly, volumeMetadata.isReadOnlyRemovableDevice,
+            volumeMetadata.profile, localizedLabel, volumeMetadata.providerId,
+            volumeMetadata.hasMedia, volumeMetadata.configurable,
+            volumeMetadata.watchable, volumeMetadata.source,
+            volumeMetadata.diskFileSystemType || '', volumeMetadata.iconSet,
+            volumeMetadata.driveLabel, volumeMetadata.remoteMountPath,
+            volumeMetadata.vmType);
+      })
+      .then(async (volumeInfo) => {
+        // resolveDisplayRoot() is a promise, but instead of using await here,
+        // we just pass a onSuccess function to it, because we don't want to it
+        // to interfere the startup time.
+        volumeInfo.resolveDisplayRoot(() => {
+          getStore().dispatch(addVolume({volumeMetadata, volumeInfo}));
+        });
+        return volumeInfo;
+      })
+      .catch(error => {
+        console.warn(`Cannot mount file system '${volumeMetadata.volumeId}': ${
+            error.stack || error}`);
+
+        // TODO(crbug/847729): Report a mount error via UMA.
+
+        return new VolumeInfoImpl(
+            volumeMetadata.volumeType, volumeMetadata.volumeId,
+            null,  // File system is not found.
+            volumeMetadata.mountCondition, volumeMetadata.deviceType,
+            volumeMetadata.devicePath, volumeMetadata.isReadOnly,
+            volumeMetadata.isReadOnlyRemovableDevice, volumeMetadata.profile,
+            localizedLabel, volumeMetadata.providerId, volumeMetadata.hasMedia,
+            volumeMetadata.configurable, volumeMetadata.watchable,
+            volumeMetadata.source, volumeMetadata.diskFileSystemType || '',
+            volumeMetadata.iconSet, volumeMetadata.driveLabel,
+            volumeMetadata.remoteMountPath, volumeMetadata.vmType);
+      });
+}
+
 
 type VolumeAlreadyMountedEvent = Event&{
   volumeId: string,
@@ -67,7 +201,8 @@
   private waitForInitialization_: Promise<void> =
       new Promise(resolve => this.finishInitialization_ = resolve);
 
-  constructor() {
+  constructor(
+      private createVolumeInfo_: typeof createVolumeInfo = createVolumeInfo) {
     super();
 
     chrome.fileManagerPrivate.onDriveConnectionStatusChanged.addListener(
@@ -191,7 +326,7 @@
           console.debug(`Initializing volume #${idx} '${volumeId}'`);
           // createVolumeInfo() requests the filesystem and resolve its root,
           // after that it only creates a VolumeInfo.
-          volumeInfo = await volumeManagerUtil.createVolumeInfo(volumeMetadata);
+          volumeInfo = await this.createVolumeInfo_(volumeMetadata);
           // Add addVolumeInfo_() changes the VolumeInfoList which propagates
           // to the foreground.
           this.addVolumeInfo_(volumeInfo);
@@ -257,8 +392,7 @@
 
             let volumeInfo;
             try {
-              volumeInfo =
-                  await volumeManagerUtil.createVolumeInfo(volumeMetadata);
+              volumeInfo = await this.createVolumeInfo_(volumeMetadata);
             } catch (error: any) {
               console.warn(
                   'Unable to create volumeInfo for ' +
@@ -579,8 +713,7 @@
           successCallbacks: [successCallback as RequestSuccessCallback],
           errorCallbacks: [errorCallback],
 
-          timeout: setTimeout(
-              this.onTimeout_.bind(this, key), volumeManagerUtil.TIMEOUT),
+          timeout: setTimeout(this.onTimeout_.bind(this, key), TIMEOUT),
         };
       }
     });
@@ -626,7 +759,7 @@
       request.successCallbacks.map(cb => cb(volumeInfo));
 
     } else {
-      volumeManagerUtil.validateError(status);
+      validateError(status);
       request.errorCallbacks.map(cb => cb(status));
     }
   }
diff --git a/ui/file_manager/file_manager/background/js/volume_manager_unittest.js b/ui/file_manager/file_manager/background/js/volume_manager_unittest.js
deleted file mode 100644
index 891c155..0000000
--- a/ui/file_manager/file_manager/background/js/volume_manager_unittest.js
+++ /dev/null
@@ -1,878 +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.
-
-import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chromeos/chai_assert.js';
-
-import {installMockChrome, MockCommandLinePrivate} from '../../common/js/mock_chrome.js';
-import {MockDirectoryEntry, MockFileEntry, MockFileSystem} from '../../common/js/mock_entry.js';
-import {assertRejected, reportPromise, waitUntil} from '../../common/js/test_error_reporting.js';
-import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js';
-
-import {VolumeInfoImpl} from './volume_info_impl.js';
-import {volumeManagerFactory} from './volume_manager_factory.js';
-import {VolumeManagerImpl} from './volume_manager_impl.js';
-import {volumeManagerUtil} from './volume_manager_util.js';
-
-// @ts-ignore: error TS7034: Variable 'mockChrome' implicitly has type 'any' in
-// some locations where its type cannot be determined.
-let mockChrome;
-// @ts-ignore: error TS7034: Variable 'mockData' implicitly has type 'any' in
-// some locations where its type cannot be determined.
-let mockData;
-// @ts-ignore: error TS7034: Variable 'createVolumeInfoOriginal' implicitly has
-// type 'any' in some locations where its type cannot be determined.
-let createVolumeInfoOriginal;
-// @ts-ignore: error TS7034: Variable 'webkitResolveLocalFileSystemURLOriginal'
-// implicitly has type 'any' in some locations where its type cannot be
-// determined.
-let webkitResolveLocalFileSystemURLOriginal;
-
-export function setUp() {
-  mockData = {
-    mountSourcePath_: null,
-    onMountCompletedListeners_: [],
-    onDriveConnectionStatusChangedListeners_: [],
-    driveConnectionState_: 'ONLINE',
-    volumeMetadataList_: [],
-    password: undefined,
-    // @ts-ignore: error TS7006: Parameter 'state' implicitly has an 'any' type.
-    setDriveConnectionState(state) {
-      // @ts-ignore: error TS7005: Variable 'mockData' implicitly has an 'any'
-      // type.
-      mockData.driveConnectionState_ = state;
-      /** @type {!EventTarget} */ (
-          chrome.fileManagerPrivate.onDriveConnectionStatusChanged)
-          .dispatchEvent(new Event('anything'));
-    },
-  };
-
-  // Set up mock of chrome.fileManagerPrivate APIs.
-  mockChrome = {
-    fileManagerPrivate: {
-      // @ts-ignore: error TS7006: Parameter 'callback' implicitly has an 'any'
-      // type.
-      addMount: function(fileUrl, password, callback) {
-        // @ts-ignore: error TS7005: Variable 'mockData' implicitly has an 'any'
-        // type.
-        mockData.password = password;
-        // @ts-ignore: error TS7005: Variable 'mockData' implicitly has an 'any'
-        // type.
-        callback(mockData.mountSourcePath_);
-      },
-      // @ts-ignore: error TS7006: Parameter 'callback' implicitly has an 'any'
-      // type.
-      getVolumeRoot: function(options, callback) {
-        // @ts-ignore: error TS7005: Variable 'mockData' implicitly has an 'any'
-        // type.
-        if (!(options.volumeId in mockData.fileSystemMap_)) {
-          // @ts-ignore: error TS2339: Property 'runtime' does not exist on type
-          // 'typeof chrome'.
-          chrome.runtime.lastError = {message: 'Not found.'};
-        }
-        // @ts-ignore: error TS7005: Variable 'mockData' implicitly has an 'any'
-        // type.
-        callback(mockData.fileSystemMap_[options.volumeId].root);
-      },
-      // @ts-ignore: error TS7006: Parameter 'callback' implicitly has an 'any'
-      // type.
-      removeMount: function(volumeId, callback) {
-        const event = {
-          eventType: 'unmount',
-          status: 'success',
-          volumeMetadata: {volumeId: volumeId},
-        };
-        // @ts-ignore: error TS7005: Variable 'mockChrome' implicitly has an
-        // 'any' type.
-        mockChrome.fileManagerPrivate.onMountCompleted.dispatchEvent(event);
-        callback();
-      },
-      onDriveConnectionStatusChanged: {
-        // @ts-ignore: error TS7006: Parameter 'listener' implicitly has an
-        // 'any' type.
-        addListener: function(listener) {
-          // @ts-ignore: error TS7005: Variable 'mockData' implicitly has an
-          // 'any' type.
-          mockData.onDriveConnectionStatusChangedListeners_.push(listener);
-        },
-        // @ts-ignore: error TS7006: Parameter 'event' implicitly has an 'any'
-        // type.
-        dispatchEvent: function(event) {
-          // @ts-ignore: error TS7005: Variable 'mockData' implicitly has an
-          // 'any' type.
-          mockData.onDriveConnectionStatusChangedListeners_.forEach(
-              // @ts-ignore: error TS7006: Parameter 'listener' implicitly has
-              // an 'any' type.
-              listener => {
-                listener(event);
-              });
-        },
-      },
-      onMountCompleted: {
-        // @ts-ignore: error TS7006: Parameter 'listener' implicitly has an
-        // 'any' type.
-        addListener: function(listener) {
-          // @ts-ignore: error TS7005: Variable 'mockData' implicitly has an
-          // 'any' type.
-          mockData.onMountCompletedListeners_.push(listener);
-        },
-        // @ts-ignore: error TS7006: Parameter 'event' implicitly has an 'any'
-        // type.
-        dispatchEvent: function(event) {
-          // @ts-ignore: error TS7005: Variable 'mockData' implicitly has an
-          // 'any' type.
-          mockData.onMountCompletedListeners_.forEach(
-              // @ts-ignore: error TS7006: Parameter 'listener' implicitly has
-              // an 'any' type.
-              listener => listener(event));
-        },
-      },
-      // @ts-ignore: error TS7006: Parameter 'callback' implicitly has an 'any'
-      // type.
-      getDriveConnectionState: function(callback) {
-        // @ts-ignore: error TS7005: Variable 'mockData' implicitly has an 'any'
-        // type.
-        callback(mockData.driveConnectionState_);
-      },
-      // @ts-ignore: error TS7006: Parameter 'callback' implicitly has an 'any'
-      // type.
-      getVolumeMetadataList: function(callback) {
-        // @ts-ignore: error TS7005: Variable 'mockData' implicitly has an 'any'
-        // type.
-        callback(mockData.volumeMetadataList_);
-      },
-    },
-  };
-
-  installMockChrome(mockChrome);
-  new MockCommandLinePrivate();
-  mockData.volumeMetadataList_ = [
-    // @ts-ignore: error TS2322: Type '{ volumeId: string; volumeLabel: string;
-    // volumeType: string; isReadOnly: false; profile: { displayName: string;
-    // isCurrentProfile: boolean; profileId: string; }; configurable: false;
-    // watchable: true; source: string; }' is not assignable to type 'never'.
-    {
-      volumeId: 'download:Downloads',
-      volumeLabel: '',
-      volumeType: VolumeManagerCommon.VolumeType.DOWNLOADS,
-      isReadOnly: false,
-      profile: getMockProfile(),
-      configurable: false,
-      watchable: true,
-      source: VolumeManagerCommon.Source.SYSTEM,
-    },
-    // @ts-ignore: error TS2322: Type '{ volumeId: string; volumeLabel: string;
-    // volumeType: string; isReadOnly: false; profile: { displayName: string;
-    // isCurrentProfile: boolean; profileId: string; }; configurable: false;
-    // watchable: true; source: string; }' is not assignable to type 'never'.
-    {
-      volumeId: 'drive:drive-foobar%40chromium.org-hash',
-      volumeLabel: '',
-      volumeType: VolumeManagerCommon.VolumeType.DRIVE,
-      isReadOnly: false,
-      profile: getMockProfile(),
-      configurable: false,
-      watchable: true,
-      source: VolumeManagerCommon.Source.NETWORK,
-    },
-    // @ts-ignore: error TS2322: Type '{ volumeId: string; volumeLabel: string;
-    // volumeType: string; isReadOnly: false; profile: { displayName: string;
-    // isCurrentProfile: boolean; profileId: string; }; configurable: false;
-    // watchable: true; source: string; }' is not assignable to type 'never'.
-    {
-      volumeId: 'android_files:0',
-      volumeLabel: '',
-      volumeType: VolumeManagerCommon.VolumeType.ANDROID_FILES,
-      isReadOnly: false,
-      profile: getMockProfile(),
-      configurable: false,
-      watchable: true,
-      source: VolumeManagerCommon.Source.SYSTEM,
-    },
-  ];
-  // @ts-ignore: error TS2339: Property 'fileSystemMap_' does not exist on type
-  // '{ mountSourcePath_: null; onMountCompletedListeners_: never[];
-  // onDriveConnectionStatusChangedListeners_: never[]; driveConnectionState_:
-  // string; volumeMetadataList_: never[]; password: undefined;
-  // setDriveConnectionState(state: any): void; }'.
-  mockData.fileSystemMap_ = {
-    'download:Downloads': new MockFileSystem('download:Downloads'),
-    'drive:drive-foobar%40chromium.org-hash':
-        new MockFileSystem('drive:drive-foobar%40chromium.org-hash'),
-    'android_files:0': new MockFileSystem('android_files:0'),
-  };
-
-  const driveFs =
-      // @ts-ignore: error TS2339: Property 'fileSystemMap_' does not exist on
-      // type '{ mountSourcePath_: null; onMountCompletedListeners_: never[];
-      // onDriveConnectionStatusChangedListeners_: never[];
-      // driveConnectionState_: string; volumeMetadataList_: never[]; password:
-      // undefined; setDriveConnectionState(state: any): void; }'.
-      mockData.fileSystemMap_['drive:drive-foobar%40chromium.org-hash'];
-  driveFs.populate(['/root/', '/team_drives/', '/Computers/']);
-
-  // Mock window.webkitResolveLocalFileSystemURL to return entries for DriveFS.
-  webkitResolveLocalFileSystemURLOriginal =
-      window.webkitResolveLocalFileSystemURL;
-  window.webkitResolveLocalFileSystemURL = (url, success) => {
-    const match = url.match(/^filesystem:drive:.*(\/.*)/);
-    if (match) {
-      const path = match[1];
-      const entry = driveFs.entries[path];
-      if (entry) {
-        return setTimeout(success, 0, entry);
-      }
-    }
-    throw new DOMException('Unknown drive url: ' + url, 'NotFoundError');
-  };
-
-  createVolumeInfoOriginal = volumeManagerUtil.createVolumeInfo;
-}
-
-export function tearDown() {
-  volumeManagerFactory.revokeInstanceForTesting();
-  // To avoid a closure warning assigning to |chrome|, tearDown() does not
-  // balance the call to installMockChrome() here.
-
-  // Restore the createVolumeInfo() function.
-  // @ts-ignore: error TS7005: Variable 'createVolumeInfoOriginal' implicitly
-  // has an 'any' type.
-  volumeManagerUtil.createVolumeInfo = createVolumeInfoOriginal;
-
-  // Restore window.webkitResolveLocalFileSystemURL.
-  window.webkitResolveLocalFileSystemURL =
-      // @ts-ignore: error TS7005: Variable
-      // 'webkitResolveLocalFileSystemURLOriginal' implicitly has an 'any' type.
-      webkitResolveLocalFileSystemURLOriginal;
-}
-
-// @ts-ignore: error TS7006: Parameter 'volumeManager' implicitly has an 'any'
-// type.
-async function waitAllVolumes(volumeManager) {
-  // Drive + Downloads + Android:
-  await waitUntil(() => volumeManager.volumeInfoList.length === 3);
-}
-
-/**
- * Returns a mock profile.
- *
- * @return {{displayName:string, isCurrentProfile:boolean, profileId:string}}
- *     Mock profile
- */
-function getMockProfile() {
-  return {
-    displayName: 'foobar@chromium.org',
-    isCurrentProfile: true,
-    profileId: '',
-  };
-}
-
-/** @param {()=>void} done */
-export async function testGetVolumeInfo(done) {
-  const volumeManager = await volumeManagerFactory.getInstance();
-
-  const entry = MockFileEntry.create(
-      new MockFileSystem('download:Downloads'), '/foo/bar/bla.zip');
-
-  await waitAllVolumes(volumeManager);
-
-  const volumeInfo = volumeManager.getVolumeInfo(entry);
-  // @ts-ignore: error TS18047: 'volumeInfo' is possibly 'null'.
-  assertEquals('download:Downloads', volumeInfo.volumeId);
-  // @ts-ignore: error TS18047: 'volumeInfo' is possibly 'null'.
-  assertEquals(VolumeManagerCommon.VolumeType.DOWNLOADS, volumeInfo.volumeType);
-
-  done();
-}
-
-/**
- * Tests that an unresponsive volume doesn't lock the whole Volume Manager
- * initialization.
- * @param {()=>void} done
- */
-export async function testUnresponsiveVolumeStartUp(done) {
-  let unblock;
-  const fileManagerPrivate = chrome.fileManagerPrivate;
-
-  // Replace chrome.fileManagerPrivate.getVolumeRoot() to emulate 1
-  // volume not resolving.
-  const origGetVolumeRoot = fileManagerPrivate.getVolumeRoot;
-
-  fileManagerPrivate.getVolumeRoot = (options, callback) => {
-    if (options.volumeId === 'download:Downloads') {
-      console.log(`blocking the resolve for ${options.volumeId}`);
-      unblock = () => origGetVolumeRoot(options, callback);
-      return;
-    }
-    return origGetVolumeRoot(options, callback);
-  };
-
-  // getInstance() calls and waits for initialize(), which shouldn't get stuck
-  // waiting for the all volumes to resolve.
-  const volumeManager = await volumeManagerFactory.getInstance();
-
-  // Wait 2 out 3 volumes to be ready.
-  await waitUntil(() => volumeManager.volumeInfoList.length === 2);
-
-  // Unblock the unresponsive volume and check if it gets available:
-  // @ts-ignore: error TS2722: Cannot invoke an object which is possibly
-  // 'undefined'.
-  unblock();
-  await waitUntil(() => volumeManager.volumeInfoList.length === 3);
-
-  done();
-}
-
-/** @param {()=>void} callback */
-export function testGetDriveConnectionState(callback) {
-  reportPromise(
-      volumeManagerFactory.getInstance().then(volumeManager => {
-        // Default connection state is online
-        assertEquals(
-            chrome.fileManagerPrivate.DriveConnectionStateType.ONLINE,
-            volumeManager.getDriveConnectionState());
-
-        // Sets it to offline.
-        // @ts-ignore: error TS7005: Variable 'mockData' implicitly has an 'any'
-        // type.
-        mockData.setDriveConnectionState(
-            chrome.fileManagerPrivate.DriveConnectionStateType.OFFLINE);
-        assertEquals(
-            chrome.fileManagerPrivate.DriveConnectionStateType.OFFLINE,
-            volumeManager.getDriveConnectionState());
-
-        // Sets it back to online
-        // @ts-ignore: error TS7005: Variable 'mockData' implicitly has an 'any'
-        // type.
-        mockData.setDriveConnectionState(
-            chrome.fileManagerPrivate.DriveConnectionStateType.ONLINE);
-        assertEquals(
-            chrome.fileManagerPrivate.DriveConnectionStateType.ONLINE,
-            volumeManager.getDriveConnectionState());
-      }),
-      callback);
-}
-
-/** @param {()=>void} callback */
-export function testMountArchiveAndUnmount(callback) {
-  const test = async () => {
-    // Set states of mock fileManagerPrivate APIs.
-    const mountSourcePath = '/usr/local/home/test/Downloads/foobar.zip';
-    // @ts-ignore: error TS7005: Variable 'mockData' implicitly has an 'any'
-    // type.
-    mockData.mountSourcePath_ = mountSourcePath;
-    // @ts-ignore: error TS7005: Variable 'mockData' implicitly has an 'any'
-    // type.
-    mockData.fileSystemMap_['archive:foobar.zip'] =
-        new MockFileSystem('archive:foobar.zip');
-
-    const volumeManager = await volumeManagerFactory.getInstance();
-
-    // Drive + Downloads + Android.
-    const numberOfVolumes = 3;
-    await waitAllVolumes(volumeManager);
-
-    // Mount an archive
-    const password = 'My Password';
-    const mounted = volumeManager.mountArchive(
-        'filesystem:chrome-extension://extensionid/external/' +
-            'Downloads-test/foobar.zip',
-        password);
-
-    // @ts-ignore: error TS7005: Variable 'mockChrome' implicitly has an 'any'
-    // type.
-    mockChrome.fileManagerPrivate.onMountCompleted.dispatchEvent({
-      eventType: 'mount',
-      status: 'success',
-      volumeMetadata: {
-        volumeId: 'archive:foobar.zip',
-        volumeLabel: 'foobar.zip',
-        volumeType: VolumeManagerCommon.VolumeType.ARCHIVE,
-        isReadOnly: true,
-        sourcePath: mountSourcePath,
-        profile: getMockProfile(),
-        configurable: false,
-        watchable: true,
-        source: VolumeManagerCommon.Source.FILE,
-      },
-    });
-
-    await mounted;
-
-    assertEquals(numberOfVolumes + 1, volumeManager.volumeInfoList.length);
-    // @ts-ignore: error TS7005: Variable 'mockData' implicitly has an 'any'
-    // type.
-    assertEquals(password, mockData.password);
-
-    // Unmount the mounted archive
-    const entry = MockFileEntry.create(
-        new MockFileSystem('archive:foobar.zip'), '/foo.txt');
-    const volumeInfo = volumeManager.getVolumeInfo(entry);
-    // @ts-ignore: error TS2345: Argument of type 'VolumeInfo | null' is not
-    // assignable to parameter of type 'VolumeInfo'.
-    await volumeManager.unmount(volumeInfo);
-
-    await waitUntil(
-        () => volumeManager.volumeInfoList.length === numberOfVolumes);
-    assertEquals(numberOfVolumes, volumeManager.volumeInfoList.length);
-  };
-
-  reportPromise(test(), callback);
-}
-
-/** @param {()=>void} callback */
-export function testCancelMountingArchive(callback) {
-  const test = async () => {
-    // Set states of mock fileManagerPrivate APIs.
-    const mountSourcePath = '/usr/local/home/test/Downloads/foobar.zip';
-    // @ts-ignore: error TS7005: Variable 'mockData' implicitly has an 'any'
-    // type.
-    mockData.mountSourcePath_ = mountSourcePath;
-    // @ts-ignore: error TS7005: Variable 'mockData' implicitly has an 'any'
-    // type.
-    mockData.fileSystemMap_['archive:foobar.zip'] =
-        new MockFileSystem('archive:foobar.zip');
-
-    const volumeManager = await volumeManagerFactory.getInstance();
-
-    // Drive + Downloads + Android.
-    const numberOfVolumes = 3;
-    await waitAllVolumes(volumeManager);
-
-    setTimeout(
-        // @ts-ignore: error TS7005: Variable 'mockChrome' implicitly has an
-        // 'any' type.
-        () => mockChrome.fileManagerPrivate.onMountCompleted.dispatchEvent({
-          eventType: 'mount',
-          status: VolumeManagerCommon.VolumeError.CANCELLED,
-          volumeMetadata: {
-            volumeId: null,
-            volumeLabel: null,
-            volumeType: null,
-            isReadOnly: null,
-            sourcePath: mountSourcePath,
-            profile: null,
-            configurable: null,
-            watchable: null,
-            source: null,
-          },
-        }));
-
-    try {
-      await volumeManager.mountArchive(
-          'filesystem:chrome-extension://extensionid/external/' +
-              'Downloads-test/foobar.zip',
-          'My Password');
-    } catch (error) {
-      assertEquals(error, VolumeManagerCommon.VolumeError.CANCELLED);
-    }
-
-    assertEquals(numberOfVolumes, volumeManager.volumeInfoList.length);
-  };
-
-  reportPromise(test(), callback);
-}
-
-// @ts-ignore: error TS7006: Parameter 'done' implicitly has an 'any' type.
-export async function testGetCurrentProfileVolumeInfo(done) {
-  const volumeManager = await volumeManagerFactory.getInstance();
-  await waitAllVolumes(volumeManager);
-
-  const volumeInfo = volumeManager.getCurrentProfileVolumeInfo(
-      VolumeManagerCommon.VolumeType.DRIVE);
-
-  // @ts-ignore: error TS18047: 'volumeInfo' is possibly 'null'.
-  assertEquals('drive:drive-foobar%40chromium.org-hash', volumeInfo.volumeId);
-  // @ts-ignore: error TS18047: 'volumeInfo' is possibly 'null'.
-  assertEquals(VolumeManagerCommon.VolumeType.DRIVE, volumeInfo.volumeType);
-
-  done();
-}
-
-// @ts-ignore: error TS7006: Parameter 'done' implicitly has an 'any' type.
-export async function testGetLocationInfo(done) {
-  const volumeManager = await volumeManagerFactory.getInstance();
-  await waitAllVolumes(volumeManager);
-
-  const downloadEntry = MockFileEntry.create(
-      new MockFileSystem('download:Downloads'), '/foo/bar/bla.zip');
-  const downloadLocationInfo = volumeManager.getLocationInfo(downloadEntry);
-  assertEquals(
-      // @ts-ignore: error TS18047: 'downloadLocationInfo' is possibly 'null'.
-      VolumeManagerCommon.RootType.DOWNLOADS, downloadLocationInfo.rootType);
-  // @ts-ignore: error TS18047: 'downloadLocationInfo' is possibly 'null'.
-  assertFalse(downloadLocationInfo.hasFixedLabel);
-  // @ts-ignore: error TS18047: 'downloadLocationInfo' is possibly 'null'.
-  assertFalse(downloadLocationInfo.isReadOnly);
-  // @ts-ignore: error TS18047: 'downloadLocationInfo' is possibly 'null'.
-  assertFalse(downloadLocationInfo.isRootEntry);
-
-  const driveEntry = MockFileEntry.create(
-      new MockFileSystem('drive:drive-foobar%40chromium.org-hash'), '/root');
-  const driveLocationInfo = volumeManager.getLocationInfo(driveEntry);
-  // @ts-ignore: error TS18047: 'driveLocationInfo' is possibly 'null'.
-  assertEquals(VolumeManagerCommon.RootType.DRIVE, driveLocationInfo.rootType);
-  // @ts-ignore: error TS18047: 'driveLocationInfo' is possibly 'null'.
-  assertTrue(driveLocationInfo.hasFixedLabel);
-  // @ts-ignore: error TS18047: 'driveLocationInfo' is possibly 'null'.
-  assertFalse(driveLocationInfo.isReadOnly);
-  // @ts-ignore: error TS18047: 'driveLocationInfo' is possibly 'null'.
-  assertTrue(driveLocationInfo.isRootEntry);
-
-  const teamDrivesGrandRoot = MockFileEntry.create(
-      new MockFileSystem('drive:drive-foobar%40chromium.org-hash'),
-      '/team_drives');
-  const teamDrivesGrandRootLocationInfo =
-      volumeManager.getLocationInfo(teamDrivesGrandRoot);
-  assertEquals(
-      VolumeManagerCommon.RootType.SHARED_DRIVES_GRAND_ROOT,
-      // @ts-ignore: error TS18047: 'teamDrivesGrandRootLocationInfo' is
-      // possibly 'null'.
-      teamDrivesGrandRootLocationInfo.rootType);
-  // @ts-ignore: error TS18047: 'teamDrivesGrandRootLocationInfo' is possibly
-  // 'null'.
-  assertTrue(teamDrivesGrandRootLocationInfo.hasFixedLabel);
-  // @ts-ignore: error TS18047: 'teamDrivesGrandRootLocationInfo' is possibly
-  // 'null'.
-  assertTrue(teamDrivesGrandRootLocationInfo.isReadOnly);
-  // @ts-ignore: error TS18047: 'teamDrivesGrandRootLocationInfo' is possibly
-  // 'null'.
-  assertTrue(teamDrivesGrandRootLocationInfo.isRootEntry);
-
-  const teamDrive = MockFileEntry.create(
-      new MockFileSystem('drive:drive-foobar%40chromium.org-hash'),
-      '/team_drives/MyTeamDrive');
-  const teamDriveLocationInfo = volumeManager.getLocationInfo(teamDrive);
-  assertEquals(
-      VolumeManagerCommon.RootType.SHARED_DRIVE,
-      // @ts-ignore: error TS18047: 'teamDriveLocationInfo' is possibly 'null'.
-      teamDriveLocationInfo.rootType);
-  // @ts-ignore: error TS18047: 'teamDriveLocationInfo' is possibly 'null'.
-  assertFalse(teamDriveLocationInfo.hasFixedLabel);
-  // @ts-ignore: error TS18047: 'teamDriveLocationInfo' is possibly 'null'.
-  assertFalse(teamDriveLocationInfo.isReadOnly);
-  // @ts-ignore: error TS18047: 'teamDriveLocationInfo' is possibly 'null'.
-  assertTrue(teamDriveLocationInfo.isRootEntry);
-
-  const driveFilesByIdDirectoryEntry = MockDirectoryEntry.create(
-      new MockFileSystem('drive:drive-foobar%40chromium.org-hash'),
-      '/.files-by-id/123');
-  const driveFilesByIdDirectoryLocationInfo =
-      volumeManager.getLocationInfo(driveFilesByIdDirectoryEntry);
-  assertEquals(
-      VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME,
-      // @ts-ignore: error TS18047: 'driveFilesByIdDirectoryLocationInfo' is
-      // possibly 'null'.
-      driveFilesByIdDirectoryLocationInfo.rootType);
-  // @ts-ignore: error TS18047: 'driveFilesByIdDirectoryLocationInfo' is
-  // possibly 'null'.
-  assertFalse(driveFilesByIdDirectoryLocationInfo.hasFixedLabel);
-  // @ts-ignore: error TS18047: 'driveFilesByIdDirectoryLocationInfo' is
-  // possibly 'null'.
-  assertTrue(driveFilesByIdDirectoryLocationInfo.isReadOnly);
-  // @ts-ignore: error TS18047: 'driveFilesByIdDirectoryLocationInfo' is
-  // possibly 'null'.
-  assertFalse(driveFilesByIdDirectoryLocationInfo.isRootEntry);
-
-  const driveFilesByIdEntry = MockFileEntry.create(
-      new MockFileSystem('drive:drive-foobar%40chromium.org-hash'),
-      '/.files-by-id/123/foo.txt');
-  const driveFilesByIdLocationInfo =
-      volumeManager.getLocationInfo(driveFilesByIdEntry);
-  assertEquals(
-      VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME,
-      // @ts-ignore: error TS18047: 'driveFilesByIdLocationInfo' is possibly
-      // 'null'.
-      driveFilesByIdLocationInfo.rootType);
-  // @ts-ignore: error TS18047: 'driveFilesByIdLocationInfo' is possibly 'null'.
-  assertFalse(driveFilesByIdLocationInfo.hasFixedLabel);
-  // @ts-ignore: error TS18047: 'driveFilesByIdLocationInfo' is possibly 'null'.
-  assertFalse(driveFilesByIdLocationInfo.isReadOnly);
-  // @ts-ignore: error TS18047: 'driveFilesByIdLocationInfo' is possibly 'null'.
-  assertFalse(driveFilesByIdLocationInfo.isRootEntry);
-
-  const driveShortcutTargetsByIdDirectoryEntry = MockDirectoryEntry.create(
-      new MockFileSystem('drive:drive-foobar%40chromium.org-hash'),
-      '/.shortcut-targets-by-id/abcdef');
-  const driveShortcutTargetsByIdDirectoryLocationInfo =
-      volumeManager.getLocationInfo(driveShortcutTargetsByIdDirectoryEntry);
-  assertEquals(
-      VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME,
-      // @ts-ignore: error TS18047:
-      // 'driveShortcutTargetsByIdDirectoryLocationInfo' is possibly 'null'.
-      driveShortcutTargetsByIdDirectoryLocationInfo.rootType);
-  // @ts-ignore: error TS18047: 'driveShortcutTargetsByIdDirectoryLocationInfo'
-  // is possibly 'null'.
-  assertFalse(driveShortcutTargetsByIdDirectoryLocationInfo.hasFixedLabel);
-  // @ts-ignore: error TS18047: 'driveShortcutTargetsByIdDirectoryLocationInfo'
-  // is possibly 'null'.
-  assertTrue(driveShortcutTargetsByIdDirectoryLocationInfo.isReadOnly);
-  // @ts-ignore: error TS18047: 'driveShortcutTargetsByIdDirectoryLocationInfo'
-  // is possibly 'null'.
-  assertFalse(driveShortcutTargetsByIdDirectoryLocationInfo.isRootEntry);
-
-  const driveShortcutTargetsByIdEntry = MockDirectoryEntry.create(
-      new MockFileSystem('drive:drive-foobar%40chromium.org-hash'),
-      '/.shortcut-targets-by-id/abcdef/foo');
-  const driveShortcutTargetsByIdLocationInfo =
-      volumeManager.getLocationInfo(driveShortcutTargetsByIdEntry);
-  assertEquals(
-      VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME,
-      // @ts-ignore: error TS18047: 'driveShortcutTargetsByIdLocationInfo' is
-      // possibly 'null'.
-      driveShortcutTargetsByIdLocationInfo.rootType);
-  // @ts-ignore: error TS18047: 'driveShortcutTargetsByIdLocationInfo' is
-  // possibly 'null'.
-  assertFalse(driveShortcutTargetsByIdLocationInfo.hasFixedLabel);
-  // @ts-ignore: error TS18047: 'driveShortcutTargetsByIdLocationInfo' is
-  // possibly 'null'.
-  assertFalse(driveShortcutTargetsByIdLocationInfo.isReadOnly);
-  // @ts-ignore: error TS18047: 'driveShortcutTargetsByIdLocationInfo' is
-  // possibly 'null'.
-  assertFalse(driveShortcutTargetsByIdLocationInfo.isRootEntry);
-
-  const androidRoot =
-      MockFileEntry.create(new MockFileSystem('android_files:0'), '/');
-  const androidRootLocationInfo = volumeManager.getLocationInfo(androidRoot);
-  // @ts-ignore: error TS18047: 'androidRootLocationInfo' is possibly 'null'.
-  assertTrue(androidRootLocationInfo.isReadOnly);
-  // @ts-ignore: error TS18047: 'androidRootLocationInfo' is possibly 'null'.
-  assertTrue(androidRootLocationInfo.isRootEntry);
-
-  const androidSubFolder =
-      MockFileEntry.create(new MockFileSystem('android_files:0'), '/Pictures');
-  const androidSubFolderLocationInfo =
-      volumeManager.getLocationInfo(androidSubFolder);
-  // @ts-ignore: error TS18047: 'androidSubFolderLocationInfo' is possibly
-  // 'null'.
-  assertFalse(androidSubFolderLocationInfo.isReadOnly);
-  // @ts-ignore: error TS18047: 'androidSubFolderLocationInfo' is possibly
-  // 'null'.
-  assertFalse(androidSubFolderLocationInfo.isRootEntry);
-
-  const computersGrandRoot = MockFileEntry.create(
-      new MockFileSystem('drive:drive-foobar%40chromium.org-hash'),
-      '/Computers');
-  const computersGrandRootLocationInfo =
-      volumeManager.getLocationInfo(computersGrandRoot);
-  assertEquals(
-      VolumeManagerCommon.RootType.COMPUTERS_GRAND_ROOT,
-      // @ts-ignore: error TS18047: 'computersGrandRootLocationInfo' is possibly
-      // 'null'.
-      computersGrandRootLocationInfo.rootType);
-  // @ts-ignore: error TS18047: 'computersGrandRootLocationInfo' is possibly
-  // 'null'.
-  assertTrue(computersGrandRootLocationInfo.hasFixedLabel);
-  // @ts-ignore: error TS18047: 'computersGrandRootLocationInfo' is possibly
-  // 'null'.
-  assertTrue(computersGrandRootLocationInfo.isReadOnly);
-  // @ts-ignore: error TS18047: 'computersGrandRootLocationInfo' is possibly
-  // 'null'.
-  assertTrue(computersGrandRootLocationInfo.isRootEntry);
-
-  const computer = MockFileEntry.create(
-      new MockFileSystem('drive:drive-foobar%40chromium.org-hash'),
-      '/Computers/MyComputer');
-  const computerLocationInfo = volumeManager.getLocationInfo(computer);
-  assertEquals(
-      // @ts-ignore: error TS18047: 'computerLocationInfo' is possibly 'null'.
-      VolumeManagerCommon.RootType.COMPUTER, computerLocationInfo.rootType);
-  // @ts-ignore: error TS18047: 'computerLocationInfo' is possibly 'null'.
-  assertFalse(computerLocationInfo.hasFixedLabel);
-  // @ts-ignore: error TS18047: 'computerLocationInfo' is possibly 'null'.
-  assertTrue(computerLocationInfo.isReadOnly);
-  // @ts-ignore: error TS18047: 'computerLocationInfo' is possibly 'null'.
-  assertTrue(computerLocationInfo.isRootEntry);
-
-  done();
-}
-
-/** @param {()=>void} callback */
-export function testWhenReady(callback) {
-  volumeManagerFactory.getInstance().then((volumeManager) => {
-    const promiseBeforeAdd = volumeManager.whenVolumeInfoReady('volumeId');
-    const volumeInfo = new VolumeInfoImpl(
-        /* volumeType */ VolumeManagerCommon.VolumeType.MY_FILES,
-        /* volumeId */ 'volumeId',
-        // @ts-ignore: error TS2345: Argument of type 'null' is not assignable
-        // to parameter of type 'FileSystem'.
-        /* fileSystem */ null,
-        /* error */ undefined,
-        /* deviceType */ undefined,
-        /* devicePath */ undefined,
-        /* isReadOnly */ false,
-        /* isReadOnlyRemovableDevice */ false,
-        /* profile */ {displayName: '', isCurrentProfile: true},
-        /* label */ 'testLabel',
-        /* extensionid */ undefined,
-        /* hasMedia */ false,
-        /* configurable */ false,
-        /* watchable */ true,
-        /* source */ VolumeManagerCommon.Source.FILE,
-        /* diskFileSystemType */ VolumeManagerCommon.FileSystemType.UNKNOWN,
-        /* iconSet */ {},
-        /* driveLabel */ 'TEST_DRIVE_LABEL',
-        /* remoteMountPath*/ '',
-        /* vmType*/ undefined);
-    volumeManager.volumeInfoList.add(volumeInfo);
-    const promiseAfterAdd = volumeManager.whenVolumeInfoReady('volumeId');
-    reportPromise(
-        Promise.all([promiseBeforeAdd, promiseAfterAdd]).then((volumes) => {
-          assertEquals(volumeInfo, volumes[0]);
-          assertEquals(volumeInfo, volumes[1]);
-        }),
-        callback);
-  });
-}
-
-/** @param {()=>void} callback */
-export function testDriveMountedDuringInitialization(callback) {
-  const test = async () => {
-    const sendVolumeMetadataListPromise = new Promise(resolve => {
-      chrome.fileManagerPrivate.getVolumeMetadataList = resolve;
-    });
-
-    // Start volume manager initialization.
-    const volumeManagerPromise = volumeManagerFactory.getInstance();
-
-    // Drive is mounted during initialization.
-    // @ts-ignore: error TS7005: Variable 'mockChrome' implicitly has an 'any'
-    // type.
-    mockChrome.fileManagerPrivate.onMountCompleted.dispatchEvent({
-      eventType: 'mount',
-      status: 'success',
-      volumeMetadata: {
-        volumeId: 'drive:drive-foobar%40chromium.org-hash',
-        volumeType: VolumeManagerCommon.VolumeType.DRIVE,
-        sourcePath: '/drive',
-        profile: getMockProfile(),
-      },
-    });
-
-    // Wait until volume manager initialization calls getVolumeMetadataList().
-    const sendVolumeMetadataList = await sendVolumeMetadataListPromise;
-
-    // Inject the callback value for getVolumeMetadataList(), making the
-    // initialization continue and finish.
-    sendVolumeMetadataList([]);
-
-    // Wait for volume manager to finish initializing.
-    const volumeManager = await volumeManagerPromise;
-
-    await waitUntil(() => volumeManager.volumeInfoList.length === 1);
-
-    // Check volume manager.
-    assertTrue(!!volumeManager.getCurrentProfileVolumeInfo(
-        VolumeManagerCommon.VolumeType.DRIVE));
-  };
-
-  reportPromise(test(), callback);
-}
-
-// @ts-ignore: error TS7006: Parameter 'done' implicitly has an 'any' type.
-export function testErrorPropagatedDuringInitialization(done) {
-  chrome.fileManagerPrivate.getVolumeMetadataList = () => {
-    throw new Error('Dummy error for test purpose');
-  };
-
-  // @ts-ignore: error TS2345: Argument of type 'Promise<VolumeManager>' is not
-  // assignable to parameter of type 'Promise<void>'.
-  reportPromise(assertRejected(volumeManagerFactory.getInstance()), done);
-}
-
-/**
- * Tests that an error initializing one volume doesn't stop other volumes to be
- * initialized. crbug.com/1041340
- */
-// @ts-ignore: error TS7006: Parameter 'done' implicitly has an 'any' type.
-export async function testErrorInitializingVolume(done) {
-  // Confirm that a Drive volume is on faked getVolumeMetadataList().
-  // @ts-ignore: error TS7006: Parameter 'volumeMetadata' implicitly has an
-  // 'any' type.
-  assertTrue(mockData.volumeMetadataList_.some(volumeMetadata => {
-    return volumeMetadata.volumeType === VolumeManagerCommon.VolumeType.DRIVE;
-  }));
-
-  // Replace createVolumeInfo() to fail to create Drive volume.
-  // @ts-ignore: error TS7006: Parameter 'volumeMetadata' implicitly has an
-  // 'any' type.
-  const createVolumeInfoFake = (volumeMetadata) => {
-    if (volumeMetadata.volumeType === VolumeManagerCommon.VolumeType.DRIVE) {
-      throw new Error('Fake security error');
-    }
-
-    // For any other volume return normal value.
-    // @ts-ignore: error TS7005: Variable 'createVolumeInfoOriginal' implicitly
-    // has an 'any' type.
-    return createVolumeInfoOriginal(volumeMetadata);
-  };
-  volumeManagerUtil.createVolumeInfo = createVolumeInfoFake;
-
-  // Wait for initialization to populate volumeInfoList.
-  const volumeManager = new VolumeManagerImpl();
-  await volumeManager.initialize();
-
-  // VolumeInfoList should contain only Android and MyFiles.
-  await waitUntil(() => volumeManager.volumeInfoList.length === 2);
-
-  assertEquals(2, volumeManager.volumeInfoList.length);
-  assertEquals(
-      VolumeManagerCommon.VolumeType.DOWNLOADS,
-      volumeManager.volumeInfoList.item(0).volumeType);
-  assertEquals(
-      VolumeManagerCommon.VolumeType.ANDROID_FILES,
-      volumeManager.volumeInfoList.item(1).volumeType);
-
-  done();
-}
-
-/**
- * Tests VolumeInfoImpl doesn't raise exception if null is passed for
- * filesystem. crbug.com/1041340
- */
-// @ts-ignore: error TS7006: Parameter 'done' implicitly has an 'any' type.
-export async function testDriveWithNullFilesystem(done) {
-  // Get Drive volume metadata from faked getVolumeMetadataList().
-  const driveVolumeMetadata =
-      // @ts-ignore: error TS7006: Parameter 'volumeMetadata' implicitly has an
-      // 'any' type.
-      mockData.volumeMetadataList_.find(volumeMetadata => {
-        return volumeMetadata.volumeType ===
-            VolumeManagerCommon.VolumeType.DRIVE;
-      });
-  assertTrue(!!driveVolumeMetadata);
-
-  const localizedLabel = 'DRIVE LABEL';
-  const expectedError = 'EXPECTED ERROR DESCRIPTION';
-
-  // Create a VolumeInfo with null filesystem, in the same way that happens on
-  // volumeManagerUtil.createVolumeInfo().
-  const volumeInfo = new VolumeInfoImpl(
-      /** @type {VolumeManagerCommon.VolumeType} */
-      (driveVolumeMetadata.volumeType), driveVolumeMetadata.volumeId,
-      // @ts-ignore: error TS2345: Argument of type 'null' is not assignable to
-      // parameter of type 'FileSystem'.
-      null,  // File system is not found.
-      expectedError, driveVolumeMetadata.deviceType,
-      driveVolumeMetadata.devicePath, driveVolumeMetadata.isReadOnly,
-      driveVolumeMetadata.isReadOnlyRemovableDevice,
-      driveVolumeMetadata.profile, localizedLabel,
-      driveVolumeMetadata.providerId, driveVolumeMetadata.hasMedia,
-      driveVolumeMetadata.configurable, driveVolumeMetadata.watchable,
-      /** @type {VolumeManagerCommon.Source} */
-      (driveVolumeMetadata.source),
-      /** @type {VolumeManagerCommon.FileSystemType} */
-      (driveVolumeMetadata.diskFileSystemType), driveVolumeMetadata.iconSet,
-      driveVolumeMetadata.driveLabel, driveVolumeMetadata.remoteMountPath,
-      driveVolumeMetadata.vmType);
-
-  // Wait for trying to resolve display root, it should fail with
-  // |expectedError| if not re-throw to make the test fail.
-  await volumeInfo.resolveDisplayRoot().catch(error => {
-    if (error !== expectedError) {
-      throw error;
-    }
-  });
-
-  done();
-}
diff --git a/ui/file_manager/file_manager/background/js/volume_manager_unittest.ts b/ui/file_manager/file_manager/background/js/volume_manager_unittest.ts
new file mode 100644
index 0000000..4ce4638
--- /dev/null
+++ b/ui/file_manager/file_manager/background/js/volume_manager_unittest.ts
@@ -0,0 +1,693 @@
+// 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.
+
+import {assert} from 'chrome://resources/js/assert.js';
+import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chromeos/chai_assert.js';
+
+import {installMockChrome, MockCommandLinePrivate} from '../../common/js/mock_chrome.js';
+import {MockDirectoryEntry, MockFileEntry, MockFileSystem} from '../../common/js/mock_entry.js';
+import {assertRejected, waitUntil} from '../../common/js/test_error_reporting.js';
+import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js';
+import {VolumeManager} from '../../externs/volume_manager.js';
+
+import {VolumeInfoImpl} from './volume_info_impl.js';
+import {volumeManagerFactory} from './volume_manager_factory.js';
+import {createVolumeInfo, VolumeManagerImpl} from './volume_manager_impl.js';
+
+let mockChrome: {
+  fileManagerPrivate: Partial<typeof chrome.fileManagerPrivate>,
+};
+let mockData: {
+  mountSourcePath_: string|null,
+  onMountCompletedListeners_:
+      Array<(event: chrome.fileManagerPrivate.MountCompletedEvent) => void>,
+  onDriveConnectionStatusChangedListeners_: Array<(event: Event) => void>,
+  driveConnectionState_: chrome.fileManagerPrivate.DriveConnectionState,
+  volumeMetadataList_: chrome.fileManagerPrivate.VolumeMetadata[],
+  password: string|undefined,
+  setDriveConnectionState:
+      (state: chrome.fileManagerPrivate.DriveConnectionStateType) => void,
+  fileSystemMap_: {
+    [volumeId: string]: MockFileSystem,
+  },
+};
+let webkitResolveLocalFileSystemURLOriginal:
+    typeof window.webkitResolveLocalFileSystemURL;
+
+export function setUp() {
+  mockData = {
+    mountSourcePath_: null,
+    onMountCompletedListeners_: [],
+    onDriveConnectionStatusChangedListeners_: [],
+    driveConnectionState_:
+        {type: chrome.fileManagerPrivate.DriveConnectionStateType.ONLINE},
+    volumeMetadataList_: [],
+    password: undefined,
+    setDriveConnectionState(state) {
+      mockData.driveConnectionState_ = {type: state};
+      chrome.fileManagerPrivate.onDriveConnectionStatusChanged.dispatchEvent(
+          new Event('anything'));
+    },
+    fileSystemMap_: {},
+  };
+
+  // Set up mock of chrome.fileManagerPrivate APIs.
+  mockChrome = {
+    fileManagerPrivate: {
+      addMount: function(_, password, callback) {
+        mockData.password = password!;
+        callback(mockData.mountSourcePath_!);
+      },
+      getVolumeRoot: function(options, callback) {
+        if (!(options.volumeId in mockData.fileSystemMap_)) {
+          chrome.runtime.lastError = {message: 'Not found.'};
+        }
+        callback(mockData.fileSystemMap_[options.volumeId]!.root);
+      },
+      removeMount: function(volumeId, callback) {
+        const event = {
+          eventType: 'unmount',
+          status: 'success',
+          volumeMetadata: {volumeId: volumeId},
+        };
+        mockChrome.fileManagerPrivate.onMountCompleted.dispatchEvent(event);
+        callback();
+      },
+      onDriveConnectionStatusChanged: {
+        addListener: function(listener: (event: Event) => void) {
+          mockData.onDriveConnectionStatusChangedListeners_.push(listener);
+        },
+        dispatchEvent: function(event: Event) {
+          mockData.onDriveConnectionStatusChangedListeners_.forEach(
+              listener => {
+                listener(event);
+              });
+        },
+      },
+      onMountCompleted: {
+        addListener: function(
+            listener: (event: chrome.fileManagerPrivate.MountCompletedEvent) =>
+                void) {
+          mockData.onMountCompletedListeners_.push(listener);
+        },
+        dispatchEvent: function(
+            event: chrome.fileManagerPrivate.MountCompletedEvent) {
+          mockData.onMountCompletedListeners_.forEach(
+              listener => listener(event));
+        },
+      },
+      getDriveConnectionState: function(callback) {
+        callback(mockData.driveConnectionState_);
+      },
+      getVolumeMetadataList: function(callback) {
+        callback(mockData.volumeMetadataList_);
+      },
+    },
+  };
+
+  installMockChrome(mockChrome);
+  new MockCommandLinePrivate();
+  mockData.volumeMetadataList_ = [
+    {
+      volumeId: 'download:Downloads',
+      volumeLabel: '',
+      volumeType: VolumeManagerCommon.VolumeType.DOWNLOADS,
+      isReadOnly: false,
+      profile: getMockProfile(),
+      configurable: false,
+      watchable: true,
+      source: VolumeManagerCommon.Source.SYSTEM,
+    } as chrome.fileManagerPrivate.VolumeMetadata,
+    {
+      volumeId: 'drive:drive-foobar%40chromium.org-hash',
+      volumeLabel: '',
+      volumeType: VolumeManagerCommon.VolumeType.DRIVE,
+      isReadOnly: false,
+      profile: getMockProfile(),
+      configurable: false,
+      watchable: true,
+      source: VolumeManagerCommon.Source.NETWORK,
+    } as chrome.fileManagerPrivate.VolumeMetadata,
+    {
+      volumeId: 'android_files:0',
+      volumeLabel: '',
+      volumeType: VolumeManagerCommon.VolumeType.ANDROID_FILES,
+      isReadOnly: false,
+      profile: getMockProfile(),
+      configurable: false,
+      watchable: true,
+      source: VolumeManagerCommon.Source.SYSTEM,
+    } as chrome.fileManagerPrivate.VolumeMetadata,
+  ];
+  mockData.fileSystemMap_ = {
+    'download:Downloads': new MockFileSystem('download:Downloads'),
+    'drive:drive-foobar%40chromium.org-hash':
+        new MockFileSystem('drive:drive-foobar%40chromium.org-hash'),
+    'android_files:0': new MockFileSystem('android_files:0'),
+  };
+
+  const driveFs =
+      mockData.fileSystemMap_['drive:drive-foobar%40chromium.org-hash']!;
+  driveFs.populate(['/root/', '/team_drives/', '/Computers/']);
+
+  // Mock window.webkitResolveLocalFileSystemURL to return entries for DriveFS.
+  webkitResolveLocalFileSystemURLOriginal =
+      window.webkitResolveLocalFileSystemURL;
+  window.webkitResolveLocalFileSystemURL = (url, success) => {
+    const match = url.match(/^filesystem:drive:.*(\/.*)/);
+    if (match) {
+      const path = match[1];
+      const entry = driveFs.entries[path!];
+      if (entry) {
+        return setTimeout(success, 0, entry);
+      }
+    }
+    throw new DOMException('Unknown drive url: ' + url, 'NotFoundError');
+  };
+}
+
+export function tearDown() {
+  volumeManagerFactory.revokeInstanceForTesting();
+  // To avoid a closure warning assigning to |chrome|, tearDown() does not
+  // balance the call to installMockChrome() here.
+
+  // Restore window.webkitResolveLocalFileSystemURL.
+  window.webkitResolveLocalFileSystemURL =
+      webkitResolveLocalFileSystemURLOriginal;
+}
+
+async function waitAllVolumes(volumeManager: VolumeManager) {
+  // Drive + Downloads + Android:
+  await waitUntil(() => volumeManager.volumeInfoList.length === 3);
+}
+
+/**
+ * Returns a mock profile.
+ */
+function getMockProfile():
+    {displayName: string, isCurrentProfile: boolean, profileId: string} {
+  return {
+    displayName: 'foobar@chromium.org',
+    isCurrentProfile: true,
+    profileId: '',
+  };
+}
+
+export async function testGetVolumeInfo(done: VoidCallback) {
+  const volumeManager = await volumeManagerFactory.getInstance();
+
+  const entry = MockFileEntry.create(
+      new MockFileSystem('download:Downloads'), '/foo/bar/bla.zip');
+
+  await waitAllVolumes(volumeManager);
+
+  const volumeInfo = volumeManager.getVolumeInfo(entry);
+  assert(volumeInfo);
+  assertEquals('download:Downloads', volumeInfo.volumeId);
+  assertEquals(VolumeManagerCommon.VolumeType.DOWNLOADS, volumeInfo.volumeType);
+
+  done();
+}
+
+/**
+ * Tests that an unresponsive volume doesn't lock the whole Volume Manager
+ * initialization.
+ */
+export async function testUnresponsiveVolumeStartUp(done: VoidCallback) {
+  let unblock: VoidCallback;
+  const fileManagerPrivate = chrome.fileManagerPrivate;
+
+  // Replace chrome.fileManagerPrivate.getVolumeRoot() to emulate 1
+  // volume not resolving.
+  const origGetVolumeRoot = fileManagerPrivate.getVolumeRoot;
+
+  fileManagerPrivate.getVolumeRoot =
+      (options: chrome.fileManagerPrivate.GetVolumeRootOptions,
+       callback: DirectoryEntryCallback) => {
+        if (options.volumeId === 'download:Downloads') {
+          console.log(`blocking the resolve for ${options.volumeId}`);
+          unblock = () => origGetVolumeRoot(options, callback);
+          return;
+        }
+        return origGetVolumeRoot(options, callback);
+      };
+
+  // getInstance() calls and waits for initialize(), which shouldn't get stuck
+  // waiting for the all volumes to resolve.
+  const volumeManager = await volumeManagerFactory.getInstance();
+
+  // Wait 2 out 3 volumes to be ready.
+  await waitUntil(() => volumeManager.volumeInfoList.length === 2);
+
+  // Unblock the unresponsive volume and check if it gets available:
+  unblock!();
+  await waitUntil(() => volumeManager.volumeInfoList.length === 3);
+
+  done();
+}
+
+export async function testGetDriveConnectionState(done: VoidCallback) {
+  const volumeManager = await volumeManagerFactory.getInstance();
+  // Default connection state is online
+  assertEquals(
+      chrome.fileManagerPrivate.DriveConnectionStateType.ONLINE,
+      volumeManager.getDriveConnectionState().type);
+
+  // Sets it to offline.
+  mockData.setDriveConnectionState(
+      chrome.fileManagerPrivate.DriveConnectionStateType.OFFLINE);
+  assertEquals(
+      chrome.fileManagerPrivate.DriveConnectionStateType.OFFLINE,
+      volumeManager.getDriveConnectionState().type);
+
+  // Sets it back to online
+  mockData.setDriveConnectionState(
+      chrome.fileManagerPrivate.DriveConnectionStateType.ONLINE);
+  assertEquals(
+      chrome.fileManagerPrivate.DriveConnectionStateType.ONLINE,
+      volumeManager.getDriveConnectionState().type);
+
+  done();
+}
+
+export async function testMountArchiveAndUnmount(done: VoidCallback) {
+  // Set states of mock fileManagerPrivate APIs.
+  const mountSourcePath = '/usr/local/home/test/Downloads/foobar.zip';
+  mockData.mountSourcePath_ = mountSourcePath;
+  mockData.fileSystemMap_['archive:foobar.zip'] =
+      new MockFileSystem('archive:foobar.zip');
+
+  const volumeManager = await volumeManagerFactory.getInstance();
+
+  // Drive + Downloads + Android.
+  const numberOfVolumes = 3;
+  await waitAllVolumes(volumeManager);
+
+  // Mount an archive
+  const password = 'My Password';
+  const mounted = volumeManager.mountArchive(
+      'filesystem:chrome-extension://extensionid/external/' +
+          'Downloads-test/foobar.zip',
+      password);
+
+  mockChrome.fileManagerPrivate.onMountCompleted.dispatchEvent({
+    eventType: 'mount',
+    status: 'success',
+    volumeMetadata: {
+      volumeId: 'archive:foobar.zip',
+      volumeLabel: 'foobar.zip',
+      volumeType: VolumeManagerCommon.VolumeType.ARCHIVE,
+      isReadOnly: true,
+      sourcePath: mountSourcePath,
+      profile: getMockProfile(),
+      configurable: false,
+      watchable: true,
+      source: VolumeManagerCommon.Source.FILE,
+    },
+  });
+
+  await mounted;
+
+  assertEquals(numberOfVolumes + 1, volumeManager.volumeInfoList.length);
+  assertEquals(password, mockData.password);
+
+  // Unmount the mounted archive
+  const entry = MockFileEntry.create(
+      new MockFileSystem('archive:foobar.zip'), '/foo.txt');
+  const volumeInfo = volumeManager.getVolumeInfo(entry);
+  assert(volumeInfo);
+  await volumeManager.unmount(volumeInfo);
+
+  await waitUntil(
+      () => volumeManager.volumeInfoList.length === numberOfVolumes);
+  assertEquals(numberOfVolumes, volumeManager.volumeInfoList.length);
+
+  done();
+}
+
+export async function testCancelMountingArchive(done: VoidCallback) {
+  // Set states of mock fileManagerPrivate APIs.
+  const mountSourcePath = '/usr/local/home/test/Downloads/foobar.zip';
+  mockData.mountSourcePath_ = mountSourcePath;
+  mockData.fileSystemMap_['archive:foobar.zip'] =
+      new MockFileSystem('archive:foobar.zip');
+
+  const volumeManager = await volumeManagerFactory.getInstance();
+
+  // Drive + Downloads + Android.
+  const numberOfVolumes = 3;
+  await waitAllVolumes(volumeManager);
+
+  setTimeout(
+      () => mockChrome.fileManagerPrivate.onMountCompleted.dispatchEvent({
+        eventType: 'mount',
+        status: VolumeManagerCommon.VolumeError.CANCELLED,
+        volumeMetadata: {
+          volumeId: null,
+          volumeLabel: null,
+          volumeType: null,
+          isReadOnly: null,
+          sourcePath: mountSourcePath,
+          profile: null,
+          configurable: null,
+          watchable: null,
+          source: null,
+        },
+      }));
+
+  try {
+    await volumeManager.mountArchive(
+        'filesystem:chrome-extension://extensionid/external/' +
+            'Downloads-test/foobar.zip',
+        'My Password');
+  } catch (error) {
+    assertEquals(error, VolumeManagerCommon.VolumeError.CANCELLED);
+  }
+
+  assertEquals(numberOfVolumes, volumeManager.volumeInfoList.length);
+
+  done();
+}
+
+export async function testGetCurrentProfileVolumeInfo(done: VoidCallback) {
+  const volumeManager = await volumeManagerFactory.getInstance();
+  await waitAllVolumes(volumeManager);
+
+  const volumeInfo = volumeManager.getCurrentProfileVolumeInfo(
+      VolumeManagerCommon.VolumeType.DRIVE);
+  assert(volumeInfo);
+
+  assertEquals('drive:drive-foobar%40chromium.org-hash', volumeInfo.volumeId);
+  assertEquals(VolumeManagerCommon.VolumeType.DRIVE, volumeInfo.volumeType);
+
+  done();
+}
+
+export async function testGetLocationInfo(done: VoidCallback) {
+  const volumeManager = await volumeManagerFactory.getInstance();
+  await waitAllVolumes(volumeManager);
+
+  const downloadEntry = MockFileEntry.create(
+      new MockFileSystem('download:Downloads'), '/foo/bar/bla.zip');
+  const downloadLocationInfo = volumeManager.getLocationInfo(downloadEntry);
+  assert(downloadLocationInfo);
+  assertEquals(
+      VolumeManagerCommon.RootType.DOWNLOADS, downloadLocationInfo.rootType);
+  assertFalse(downloadLocationInfo.hasFixedLabel);
+  assertFalse(downloadLocationInfo.isReadOnly);
+  assertFalse(downloadLocationInfo.isRootEntry);
+
+  const driveEntry = MockFileEntry.create(
+      new MockFileSystem('drive:drive-foobar%40chromium.org-hash'), '/root');
+  const driveLocationInfo = volumeManager.getLocationInfo(driveEntry);
+  assert(driveLocationInfo);
+  assertEquals(VolumeManagerCommon.RootType.DRIVE, driveLocationInfo.rootType);
+  assertTrue(driveLocationInfo.hasFixedLabel);
+  assertFalse(driveLocationInfo.isReadOnly);
+  assertTrue(driveLocationInfo.isRootEntry);
+
+  const teamDrivesGrandRoot = MockFileEntry.create(
+      new MockFileSystem('drive:drive-foobar%40chromium.org-hash'),
+      '/team_drives');
+  const teamDrivesGrandRootLocationInfo =
+      volumeManager.getLocationInfo(teamDrivesGrandRoot);
+  assert(teamDrivesGrandRootLocationInfo);
+  assertEquals(
+      VolumeManagerCommon.RootType.SHARED_DRIVES_GRAND_ROOT,
+      teamDrivesGrandRootLocationInfo.rootType);
+  assertTrue(teamDrivesGrandRootLocationInfo.hasFixedLabel);
+  assertTrue(teamDrivesGrandRootLocationInfo.isReadOnly);
+  assertTrue(teamDrivesGrandRootLocationInfo.isRootEntry);
+
+  const teamDrive = MockFileEntry.create(
+      new MockFileSystem('drive:drive-foobar%40chromium.org-hash'),
+      '/team_drives/MyTeamDrive');
+  const teamDriveLocationInfo = volumeManager.getLocationInfo(teamDrive);
+  assert(teamDriveLocationInfo);
+  assertEquals(
+      VolumeManagerCommon.RootType.SHARED_DRIVE,
+      teamDriveLocationInfo.rootType);
+  assertFalse(teamDriveLocationInfo.hasFixedLabel);
+  assertFalse(teamDriveLocationInfo.isReadOnly);
+  assertTrue(teamDriveLocationInfo.isRootEntry);
+
+  const driveFilesByIdDirectoryEntry = MockDirectoryEntry.create(
+      new MockFileSystem('drive:drive-foobar%40chromium.org-hash'),
+      '/.files-by-id/123');
+  const driveFilesByIdDirectoryLocationInfo =
+      volumeManager.getLocationInfo(driveFilesByIdDirectoryEntry);
+  assert(driveFilesByIdDirectoryLocationInfo);
+  assertEquals(
+      VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME,
+      driveFilesByIdDirectoryLocationInfo.rootType);
+  assertFalse(driveFilesByIdDirectoryLocationInfo.hasFixedLabel);
+  assertTrue(driveFilesByIdDirectoryLocationInfo.isReadOnly);
+  assertFalse(driveFilesByIdDirectoryLocationInfo.isRootEntry);
+
+  const driveFilesByIdEntry = MockFileEntry.create(
+      new MockFileSystem('drive:drive-foobar%40chromium.org-hash'),
+      '/.files-by-id/123/foo.txt');
+  const driveFilesByIdLocationInfo =
+      volumeManager.getLocationInfo(driveFilesByIdEntry);
+  assert(driveFilesByIdLocationInfo);
+  assertEquals(
+      VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME,
+      driveFilesByIdLocationInfo.rootType);
+  assertFalse(driveFilesByIdLocationInfo.hasFixedLabel);
+  assertFalse(driveFilesByIdLocationInfo.isReadOnly);
+  assertFalse(driveFilesByIdLocationInfo.isRootEntry);
+
+  const driveShortcutTargetsByIdDirectoryEntry = MockDirectoryEntry.create(
+      new MockFileSystem('drive:drive-foobar%40chromium.org-hash'),
+      '/.shortcut-targets-by-id/abcdef');
+  const driveShortcutTargetsByIdDirectoryLocationInfo =
+      volumeManager.getLocationInfo(driveShortcutTargetsByIdDirectoryEntry);
+  assert(driveShortcutTargetsByIdDirectoryLocationInfo);
+  assertEquals(
+      VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME,
+      driveShortcutTargetsByIdDirectoryLocationInfo.rootType);
+  assertFalse(driveShortcutTargetsByIdDirectoryLocationInfo.hasFixedLabel);
+  assertTrue(driveShortcutTargetsByIdDirectoryLocationInfo.isReadOnly);
+  assertFalse(driveShortcutTargetsByIdDirectoryLocationInfo.isRootEntry);
+
+  const driveShortcutTargetsByIdEntry = MockDirectoryEntry.create(
+      new MockFileSystem('drive:drive-foobar%40chromium.org-hash'),
+      '/.shortcut-targets-by-id/abcdef/foo');
+  const driveShortcutTargetsByIdLocationInfo =
+      volumeManager.getLocationInfo(driveShortcutTargetsByIdEntry);
+  assert(driveShortcutTargetsByIdLocationInfo);
+  assertEquals(
+      VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME,
+      driveShortcutTargetsByIdLocationInfo.rootType);
+  assertFalse(driveShortcutTargetsByIdLocationInfo.hasFixedLabel);
+  assertFalse(driveShortcutTargetsByIdLocationInfo.isReadOnly);
+  assertFalse(driveShortcutTargetsByIdLocationInfo.isRootEntry);
+
+  const androidRoot =
+      MockFileEntry.create(new MockFileSystem('android_files:0'), '/');
+  const androidRootLocationInfo = volumeManager.getLocationInfo(androidRoot);
+  assert(androidRootLocationInfo);
+  assertTrue(androidRootLocationInfo.isReadOnly);
+  assertTrue(androidRootLocationInfo.isRootEntry);
+
+  const androidSubFolder =
+      MockFileEntry.create(new MockFileSystem('android_files:0'), '/Pictures');
+  const androidSubFolderLocationInfo =
+      volumeManager.getLocationInfo(androidSubFolder);
+  assert(androidSubFolderLocationInfo);
+  assertFalse(androidSubFolderLocationInfo.isReadOnly);
+  assertFalse(androidSubFolderLocationInfo.isRootEntry);
+
+  const computersGrandRoot = MockFileEntry.create(
+      new MockFileSystem('drive:drive-foobar%40chromium.org-hash'),
+      '/Computers');
+  const computersGrandRootLocationInfo =
+      volumeManager.getLocationInfo(computersGrandRoot);
+  assert(computersGrandRootLocationInfo);
+  assertEquals(
+      VolumeManagerCommon.RootType.COMPUTERS_GRAND_ROOT,
+      computersGrandRootLocationInfo.rootType);
+  assertTrue(computersGrandRootLocationInfo.hasFixedLabel);
+  assertTrue(computersGrandRootLocationInfo.isReadOnly);
+  assertTrue(computersGrandRootLocationInfo.isRootEntry);
+
+  const computer = MockFileEntry.create(
+      new MockFileSystem('drive:drive-foobar%40chromium.org-hash'),
+      '/Computers/MyComputer');
+  const computerLocationInfo = volumeManager.getLocationInfo(computer);
+  assert(computerLocationInfo);
+  assertEquals(
+      VolumeManagerCommon.RootType.COMPUTER, computerLocationInfo.rootType);
+  assertFalse(computerLocationInfo.hasFixedLabel);
+  assertTrue(computerLocationInfo.isReadOnly);
+  assertTrue(computerLocationInfo.isRootEntry);
+
+  done();
+}
+
+export async function testWhenReady(done: VoidCallback) {
+  const volumeManager = await volumeManagerFactory.getInstance();
+  const promiseBeforeAdd = volumeManager.whenVolumeInfoReady('volumeId');
+  const volumeInfo = new VolumeInfoImpl(
+      /* volumeType */ VolumeManagerCommon.VolumeType.MY_FILES,
+      /* volumeId */ 'volumeId',
+      /* fileSystem */ null,
+      /* error */ undefined,
+      /* deviceType */ undefined,
+      /* devicePath */ undefined,
+      /* isReadOnly */ false,
+      /* isReadOnlyRemovableDevice */ false,
+      /* profile */ {displayName: '', isCurrentProfile: true},
+      /* label */ 'testLabel',
+      /* extensionid */ undefined,
+      /* hasMedia */ false,
+      /* configurable */ false,
+      /* watchable */ true,
+      /* source */ VolumeManagerCommon.Source.FILE,
+      /* diskFileSystemType */ VolumeManagerCommon.FileSystemType.UNKNOWN,
+      /* iconSet */ {icon16x16Url: '', icon32x32Url: ''},
+      /* driveLabel */ 'TEST_DRIVE_LABEL',
+      /* remoteMountPath*/ '',
+      /* vmType*/ undefined);
+  volumeManager.volumeInfoList.add(volumeInfo);
+  const promiseAfterAdd = volumeManager.whenVolumeInfoReady('volumeId');
+  await Promise.all([promiseBeforeAdd, promiseAfterAdd]).then((volumes) => {
+    assertEquals(volumeInfo, volumes[0]);
+    assertEquals(volumeInfo, volumes[1]);
+  });
+
+  done();
+}
+
+export async function testDriveMountedDuringInitialization(done: VoidCallback) {
+  const sendVolumeMetadataListPromise = new Promise<
+      (callback: chrome.fileManagerPrivate.VolumeMetadata[]) => void>(
+      resolve => {
+        chrome.fileManagerPrivate.getVolumeMetadataList = resolve;
+      });
+
+  // Start volume manager initialization.
+  const volumeManagerPromise = volumeManagerFactory.getInstance();
+
+  // Drive is mounted during initialization.
+  mockChrome.fileManagerPrivate.onMountCompleted.dispatchEvent({
+    eventType: 'mount',
+    status: 'success',
+    volumeMetadata: {
+      volumeId: 'drive:drive-foobar%40chromium.org-hash',
+      volumeType: VolumeManagerCommon.VolumeType.DRIVE,
+      sourcePath: '/drive',
+      profile: getMockProfile(),
+    },
+  });
+
+  // Wait until volume manager initialization calls getVolumeMetadataList().
+  const sendVolumeMetadataList = await sendVolumeMetadataListPromise;
+
+  // Inject the callback value for getVolumeMetadataList(), making the
+  // initialization continue and finish.
+  sendVolumeMetadataList([]);
+
+  // Wait for volume manager to finish initializing.
+  const volumeManager = await volumeManagerPromise;
+
+  await waitUntil(() => volumeManager.volumeInfoList.length === 1);
+
+  // Check volume manager.
+  assertTrue(!!volumeManager.getCurrentProfileVolumeInfo(
+      VolumeManagerCommon.VolumeType.DRIVE));
+
+  done();
+}
+
+export async function testErrorPropagatedDuringInitialization(
+    done: VoidCallback) {
+  chrome.fileManagerPrivate.getVolumeMetadataList = () => {
+    throw new Error('Dummy error for test purpose');
+  };
+
+  await assertRejected(volumeManagerFactory.getInstance());
+
+  done();
+}
+
+/**
+ * Tests that an error initializing one volume doesn't stop other volumes to be
+ * initialized. crbug.com/1041340
+ */
+export async function testErrorInitializingVolume(done: VoidCallback) {
+  // Confirm that a Drive volume is on faked getVolumeMetadataList().
+  assertTrue(mockData.volumeMetadataList_.some(volumeMetadata => {
+    return volumeMetadata.volumeType === VolumeManagerCommon.VolumeType.DRIVE;
+  }));
+
+  // Replace createVolumeInfo() to fail to create Drive volume.
+  const createVolumeInfoFake: typeof createVolumeInfo = (volumeMetadata) => {
+    if (volumeMetadata.volumeType === VolumeManagerCommon.VolumeType.DRIVE) {
+      throw new Error('Fake security error');
+    }
+
+    // For any other volume return normal value.
+    return createVolumeInfo(volumeMetadata);
+  };
+
+  // Wait for initialization to populate volumeInfoList.
+  const volumeManager = new VolumeManagerImpl(createVolumeInfoFake);
+  await volumeManager.initialize();
+
+  // VolumeInfoList should contain only Android and MyFiles.
+  await waitUntil(() => volumeManager.volumeInfoList.length === 2);
+
+  assertEquals(2, volumeManager.volumeInfoList.length);
+  assertEquals(
+      VolumeManagerCommon.VolumeType.DOWNLOADS,
+      volumeManager.volumeInfoList.item(0).volumeType);
+  assertEquals(
+      VolumeManagerCommon.VolumeType.ANDROID_FILES,
+      volumeManager.volumeInfoList.item(1).volumeType);
+
+  done();
+}
+
+/**
+ * Tests VolumeInfoImpl doesn't raise exception if null is passed for
+ * filesystem. crbug.com/1041340
+ */
+export async function testDriveWithNullFilesystem(done: VoidCallback) {
+  // Get Drive volume metadata from faked getVolumeMetadataList().
+  const driveVolumeMetadata =
+      mockData.volumeMetadataList_.find(volumeMetadata => {
+        return volumeMetadata.volumeType ===
+            VolumeManagerCommon.VolumeType.DRIVE;
+      });
+  assert(driveVolumeMetadata);
+
+  const localizedLabel = 'DRIVE LABEL';
+  const expectedError = 'EXPECTED ERROR DESCRIPTION';
+
+  // Create a VolumeInfo with null filesystem, in the same way that happens on
+  // createVolumeInfo().
+  const volumeInfo = new VolumeInfoImpl(
+      driveVolumeMetadata.volumeType, driveVolumeMetadata.volumeId,
+      null,  // File system is not found.
+      expectedError, driveVolumeMetadata.deviceType,
+      driveVolumeMetadata.devicePath, driveVolumeMetadata.isReadOnly,
+      driveVolumeMetadata.isReadOnlyRemovableDevice,
+      driveVolumeMetadata.profile, localizedLabel,
+      driveVolumeMetadata.providerId, driveVolumeMetadata.hasMedia,
+      driveVolumeMetadata.configurable, driveVolumeMetadata.watchable,
+      driveVolumeMetadata.source, driveVolumeMetadata.diskFileSystemType || '',
+      driveVolumeMetadata.iconSet, driveVolumeMetadata.driveLabel,
+      driveVolumeMetadata.remoteMountPath, driveVolumeMetadata.vmType);
+
+  // Wait for trying to resolve display root, it should fail with
+  // |expectedError| if not re-throw to make the test fail.
+  await volumeInfo.resolveDisplayRoot().catch(error => {
+    if (error !== expectedError) {
+      throw error;
+    }
+  });
+
+  done();
+}
diff --git a/ui/file_manager/file_manager/background/js/volume_manager_util.js b/ui/file_manager/file_manager/background/js/volume_manager_util.js
deleted file mode 100644
index 3d60abe..0000000
--- a/ui/file_manager/file_manager/background/js/volume_manager_util.js
+++ /dev/null
@@ -1,192 +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.
-
-import {str} from '../../common/js/translations.js';
-import {timeoutPromise} from '../../common/js/util.js';
-import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js';
-import {addVolume} from '../../state/ducks/volumes.js';
-import {getStore} from '../../state/store.js';
-
-import {VolumeInfoImpl} from './volume_info_impl.js';
-
-/**
- * Utilities for volume manager implementation.
- */
-const volumeManagerUtil = {};
-
-/**
- * Time in milliseconds that we wait a response for general volume operations
- * such as mount, unmount, and requestFileSystem. If no response on
- * mount/unmount received the request supposed failed.
- * @const @type {number}
- */
-volumeManagerUtil.TIMEOUT = 15 * 60 * 1000;
-
-/**
- * Time in milliseconds that we wait a response for
- * chrome.fileManagerPrivate.resolveIsolatedEntries.
- * @const @type {number}
- */
-volumeManagerUtil.TIMEOUT_FOR_RESOLVE_ISOLATED_ENTRIES = 1 * 60 * 1000;
-
-/**
- * @const @type {string}
- */
-volumeManagerUtil.TIMEOUT_STR_REQUEST_FILE_SYSTEM =
-    'timeout(requestFileSystem)';
-
-/**
- * @const @type {string}
- */
-volumeManagerUtil.TIMEOUT_STR_RESOLVE_ISOLATED_ENTRIES =
-    'timeout(resolveIsolatedEntries)';
-
-/**
- * Logs a warning message if the given error is not in
- * VolumeManagerCommon.VolumeError.
- *
- * @param {string} error Status string usually received from APIs.
- */
-volumeManagerUtil.validateError = error => {
-  for (const key in VolumeManagerCommon.VolumeError) {
-    // @ts-ignore: error TS7053: Element implicitly has an 'any' type because
-    // expression of type 'string' can't be used to index type '{ TIMEOUT:
-    // string; UNKNOWN_ERROR: string; INTERNAL_ERROR: string; INVALID_ARGUMENT:
-    // string; INVALID_PATH: string; PATH_ALREADY_MOUNTED: string;
-    // PATH_NOT_MOUNTED: string; DIRECTORY_CREATION_FAILED: string; ... 9 more
-    // ...; BUSY: string; }'.
-    if (error === VolumeManagerCommon.VolumeError[key]) {
-      return;
-    }
-  }
-
-  console.warn(`Invalid mount error: ${error}`);
-};
-
-/**
- * Builds the VolumeInfo data from chrome.fileManagerPrivate.VolumeMetadata.
- * @param {chrome.fileManagerPrivate.VolumeMetadata} volumeMetadata Metadata
- * instance for the volume.
- * @return {!Promise<!import("../../externs/volume_info.js").VolumeInfo>}
- *     Promise settled with the VolumeInfo instance.
- */
-volumeManagerUtil.createVolumeInfo = async volumeMetadata => {
-  // @ts-ignore: error TS7034: Variable 'localizedLabel' implicitly has type
-  // 'any' in some locations where its type cannot be determined.
-  let localizedLabel;
-  switch (volumeMetadata.volumeType) {
-    case VolumeManagerCommon.VolumeType.DOWNLOADS:
-      localizedLabel = str('MY_FILES_ROOT_LABEL');
-      break;
-    case VolumeManagerCommon.VolumeType.DRIVE:
-      localizedLabel = str('DRIVE_DIRECTORY_LABEL');
-      break;
-    case VolumeManagerCommon.VolumeType.MEDIA_VIEW:
-      switch (VolumeManagerCommon.getMediaViewRootTypeFromVolumeId(
-          volumeMetadata.volumeId)) {
-        case VolumeManagerCommon.MediaViewRootType.IMAGES:
-          localizedLabel = str('MEDIA_VIEW_IMAGES_ROOT_LABEL');
-          break;
-        case VolumeManagerCommon.MediaViewRootType.VIDEOS:
-          localizedLabel = str('MEDIA_VIEW_VIDEOS_ROOT_LABEL');
-          break;
-        case VolumeManagerCommon.MediaViewRootType.AUDIO:
-          localizedLabel = str('MEDIA_VIEW_AUDIO_ROOT_LABEL');
-          break;
-      }
-      break;
-    case VolumeManagerCommon.VolumeType.CROSTINI:
-      localizedLabel = str('LINUX_FILES_ROOT_LABEL');
-      break;
-    case VolumeManagerCommon.VolumeType.ANDROID_FILES:
-      localizedLabel = str('ANDROID_FILES_ROOT_LABEL');
-      break;
-    default:
-      // TODO(mtomasz): Calculate volumeLabel for all types of volumes in the
-      // C++ layer.
-      localizedLabel = volumeMetadata.volumeLabel ||
-          volumeMetadata.volumeId.split(':', 2)[1];
-      break;
-  }
-
-  console.debug(`Getting file system '${volumeMetadata.volumeId}'`);
-  return timeoutPromise(
-             new Promise((resolve, reject) => {
-               chrome.fileManagerPrivate.getVolumeRoot(
-                   {
-                     volumeId: volumeMetadata.volumeId,
-                     writable: !volumeMetadata.isReadOnly,
-                   },
-                   rootDirectoryEntry => {
-                     if (chrome.runtime.lastError) {
-                       reject(chrome.runtime.lastError.message);
-                     } else {
-                       resolve(rootDirectoryEntry);
-                     }
-                   });
-             }),
-             volumeManagerUtil.TIMEOUT,
-             volumeManagerUtil.TIMEOUT_STR_REQUEST_FILE_SYSTEM + ': ' +
-                 volumeMetadata.volumeId)
-      .then(rootDirectoryEntry => {
-        console.debug(`Got file system '${volumeMetadata.volumeId}'`);
-        return new VolumeInfoImpl(
-            /** @type {VolumeManagerCommon.VolumeType} */
-            (volumeMetadata.volumeType), volumeMetadata.volumeId,
-            rootDirectoryEntry.filesystem, volumeMetadata.mountCondition,
-            volumeMetadata.deviceType, volumeMetadata.devicePath,
-            volumeMetadata.isReadOnly, volumeMetadata.isReadOnlyRemovableDevice,
-            // @ts-ignore: error TS7005: Variable 'localizedLabel' implicitly
-            // has an 'any' type.
-            volumeMetadata.profile, localizedLabel, volumeMetadata.providerId,
-            volumeMetadata.hasMedia, volumeMetadata.configurable,
-            volumeMetadata.watchable,
-            /** @type {VolumeManagerCommon.Source} */
-            (volumeMetadata.source),
-            /** @type {VolumeManagerCommon.FileSystemType} */
-            (volumeMetadata.diskFileSystemType), volumeMetadata.iconSet,
-            volumeMetadata.driveLabel, volumeMetadata.remoteMountPath,
-            volumeMetadata.vmType);
-      })
-      .then(async (volumeInfo) => {
-        // resolveDisplayRoot() is a promise, but instead of using await here,
-        // we just pass a onSuccess function to it, because we don't want to it
-        // to interfere the startup time.
-        volumeInfo.resolveDisplayRoot(() => {
-          getStore().dispatch(addVolume({volumeMetadata, volumeInfo}));
-        });
-        return volumeInfo;
-      })
-      .catch(
-          /** @param {*} error */
-          error => {
-            console.warn(`Cannot mount file system '${
-                volumeMetadata.volumeId}': ${error.stack || error}`);
-
-            // TODO(crbug/847729): Report a mount error via UMA.
-
-            return new VolumeInfoImpl(
-                /** @type {VolumeManagerCommon.VolumeType} */
-                (volumeMetadata.volumeType), volumeMetadata.volumeId,
-                // @ts-ignore: error TS2345: Argument of type 'null' is not
-                // assignable to parameter of type 'FileSystem'.
-                null,  // File system is not found.
-                volumeMetadata.mountCondition, volumeMetadata.deviceType,
-                volumeMetadata.devicePath, volumeMetadata.isReadOnly,
-                volumeMetadata.isReadOnlyRemovableDevice,
-                // @ts-ignore: error TS7005: Variable 'localizedLabel'
-                // implicitly has an 'any' type.
-                volumeMetadata.profile, localizedLabel,
-                volumeMetadata.providerId, volumeMetadata.hasMedia,
-                volumeMetadata.configurable, volumeMetadata.watchable,
-                /** @type {VolumeManagerCommon.Source} */
-                (volumeMetadata.source),
-                /** @type {VolumeManagerCommon.FileSystemType} */
-                (volumeMetadata.diskFileSystemType), volumeMetadata.iconSet,
-                volumeMetadata.driveLabel, volumeMetadata.remoteMountPath,
-                volumeMetadata.vmType);
-          });
-};
-
-export {volumeManagerUtil};
diff --git a/ui/file_manager/file_manager/common/js/test_error_reporting.js b/ui/file_manager/file_manager/common/js/test_error_reporting.js
index 1e5faa66..6077e6006 100644
--- a/ui/file_manager/file_manager/common/js/test_error_reporting.js
+++ b/ui/file_manager/file_manager/common/js/test_error_reporting.js
@@ -4,7 +4,7 @@
 
 /**
  * Asserts that promise gets rejected.
- * @param {Promise<void>} promise
+ * @param {Promise<*>} promise
  */
 export async function assertRejected(promise) {
   let triggeredError = false;
diff --git a/ui/file_manager/file_manager/containers/directory_tree_container.ts b/ui/file_manager/file_manager/containers/directory_tree_container.ts
index f7810c5..83c44db 100644
--- a/ui/file_manager/file_manager/containers/directory_tree_container.ts
+++ b/ui/file_manager/file_manager/containers/directory_tree_container.ts
@@ -386,8 +386,10 @@
           [fileData.entry as Entry], DRIVE_ENTRY_METADATA_PROPERTY_NAMES);
     }
 
-    if (!navigationRoot?.type ||
-        !NAVIGATION_TYPES_WITHOUT_CHILDREN.has(navigationRoot.type)) {
+    if (!(navigationRoot?.type &&
+          NAVIGATION_TYPES_WITHOUT_CHILDREN.has(navigationRoot.type)) &&
+        // For disabled tree root, we don't render any children inside.
+        !fileData.disabled) {
       // Handle navigation item's children.
       const newChildren = fileData.children || [];
       // Remove non-exist navigation items.
@@ -957,12 +959,14 @@
         const navigationRootData = this.navigationRoots_.find(
             navigationRoot => navigationRoot.key === fileData.entry.toURL());
         if (navigationRootData?.type === NavigationType.DRIVE) {
-          // If Drive fake root is selected and we expand it and go to the My
-          // Drive (1st child) directly.
-          if (!element.expanded) {
+          if (fileData.children.length === 0) {
+            // Drive volume is not mounted, we can only change directory to the
+            // fake drive root.
+            this.store_.dispatch(changeDirectory({toKey: entry.toURL()}));
+          } else {
+            // If Drive fake root is selected and it has Drive volume inside, we
+            // expand it and go to the My Drive (1st child) directly.
             element.expanded = true;
-          }
-          if (fileData.children && fileData.children.length > 0) {
             this.store_.dispatch(
                 changeDirectory({toKey: fileData.children[0]!}));
           }
diff --git a/ui/file_manager/file_manager/externs/volume_manager.js b/ui/file_manager/file_manager/externs/volume_manager.js
index 66cbc75..0d84755 100644
--- a/ui/file_manager/file_manager/externs/volume_manager.js
+++ b/ui/file_manager/file_manager/externs/volume_manager.js
@@ -63,9 +63,7 @@
    * @return {chrome.fileManagerPrivate.DriveConnectionState} Connection state.
    */
   getDriveConnectionState() {
-    // @ts-ignore: error TS2322: Type 'string' is not assignable to type
-    // 'DriveConnectionState'.
-    return chrome.fileManagerPrivate.DriveConnectionStateType.ONLINE;
+    return {type: chrome.fileManagerPrivate.DriveConnectionStateType.ONLINE};
   }
 
   /**
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js
index fa0ce91..089ab08 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -21,7 +21,7 @@
 import {ArrayDataModel} from '../../common/js/array_data_model.js';
 import {DialogType, isFolderDialogType} from '../../common/js/dialog_type.js';
 import {getKeyModifiers, queryDecoratedElement, queryRequiredElement} from '../../common/js/dom_utils.js';
-import {FakeEntryImpl} from '../../common/js/files_app_entry_types.js';
+import {EntryList, FakeEntryImpl} from '../../common/js/files_app_entry_types.js';
 import {FilesAppState} from '../../common/js/files_app_state.js';
 import {FilteredVolumeManager} from '../../common/js/filtered_volume_manager.js';
 import {isDlpEnabled, isGuestOsEnabled, isJellyEnabled, isNewDirectoryTreeEnabled} from '../../common/js/flags.js';
@@ -49,8 +49,8 @@
 import {updatePreferences} from '../../state/ducks/preferences.js';
 import {getDefaultSearchOptions, updateSearch} from '../../state/ducks/search.js';
 import {addUiEntry, removeUiEntry} from '../../state/ducks/ui_entries.js';
-import {trashRootKey} from '../../state/ducks/volumes.js';
-import {getEmptyState, getStore} from '../../state/store.js';
+import {driveRootEntryListKey, trashRootKey} from '../../state/ducks/volumes.js';
+import {getEmptyState, getEntry, getStore} from '../../state/store.js';
 
 import {ActionsController} from './actions_controller.js';
 import {AndroidAppListModel} from './android_app_list_model.js';
@@ -1829,7 +1829,15 @@
     if (!nextCurrentDirEntry) {
       if (isNewDirectoryTreeEnabled()) {
         const myFiles = getMyFiles(this.store_.getState());
-        nextCurrentDirEntry = myFiles.myFilesEntry;
+        // When MyFiles volume is mounted, we rely on the current directory
+        // change to make it as selected (controlled by DirectoryModel),
+        // that's why we can't set MyFiles entry list as the current directory
+        // here.
+        // TODO(b/308504417): MyFiles entry list should be selected before
+        // MyFiles volume mounts.
+        if (myFiles.myFilesVolume) {
+          nextCurrentDirEntry = myFiles.myFilesEntry;
+        }
         // @ts-ignore: error TS2339: Property 'dataModel' does not exist on type
         // 'XfTree | DirectoryTree'.
       } else if (this.ui_.directoryTree.dataModel.myFilesModel_) {
@@ -2157,23 +2165,33 @@
    */
   toggleDriveRootOnPreferencesUpdate_() {
     if (this.driveEnabled_) {
-      const driveFakeRoot = new FakeEntryImpl(
-          str('DRIVE_DIRECTORY_LABEL'),
-          VolumeManagerCommon.RootType.DRIVE_FAKE_ROOT);
-      if (!this.fakeDriveItem_) {
-        this.fakeDriveItem_ = new NavigationModelFakeItem(
-            str('DRIVE_DIRECTORY_LABEL'), NavigationModelItemType.DRIVE,
-            driveFakeRoot);
-        this.fakeDriveItem_.disabled = this.volumeManager_.isDisabled(
-            VolumeManagerCommon.VolumeType.DRIVE);
+      let driveFakeRoot = /** @type {?EntryList} */
+          (getEntry(this.store_.getState(), driveRootEntryListKey));
+      if (!driveFakeRoot) {
+        driveFakeRoot = new EntryList(
+            str('DRIVE_DIRECTORY_LABEL'),
+            VolumeManagerCommon.RootType.DRIVE_FAKE_ROOT);
+        this.store_.dispatch(addUiEntry({entry: driveFakeRoot}));
       }
       if (!isNewDirectoryTreeEnabled()) {
-        // @ts-ignore: error TS2339: Property 'dataModel' does not exist on type
-        // 'XfTree | DirectoryTree'.
+        // TODO(b/285977941): Remove the old FakeEntry based drive root.
+        const driveFakeRoot = new FakeEntryImpl(
+            str('DRIVE_DIRECTORY_LABEL'),
+            VolumeManagerCommon.RootType.DRIVE_FAKE_ROOT);
+        if (!this.fakeDriveItem_) {
+          this.fakeDriveItem_ = new NavigationModelFakeItem(
+              str('DRIVE_DIRECTORY_LABEL'), NavigationModelItemType.DRIVE,
+              driveFakeRoot);
+          this.fakeDriveItem_.disabled = this.volumeManager_.isDisabled(
+              VolumeManagerCommon.VolumeType.DRIVE);
+        }
+        // @ts-ignore: error TS2339: Property 'dataModel' does not exist on
+        // type 'XfTree | DirectoryTree'.
         this.ui_.directoryTree.dataModel.fakeDriveItem = this.fakeDriveItem_;
       }
       return;
     }
+    this.store_.dispatch(removeUiEntry({key: driveRootEntryListKey}));
     if (!isNewDirectoryTreeEnabled()) {
       // @ts-ignore: error TS2339: Property 'dataModel' does not exist on type
       // 'XfTree | DirectoryTree'.
@@ -2185,7 +2203,8 @@
   /**
    * If the root item has been disabled but it is the current visible entry,
    * navigate away from it to the default display root.
-   * @param {?NavigationModelFakeItem} rootItem The item to navigate away from.
+   * @param {?NavigationModelFakeItem} rootItem The item to navigate away
+   *     from.
    * @private
    */
   navigateAwayFromDisabledRoot_(rootItem) {
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider.js b/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider.js
deleted file mode 100644
index c9ce8a2..0000000
--- a/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider.js
+++ /dev/null
@@ -1,611 +0,0 @@
-// Copyright 2015 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {ImageLoaderClient} from 'chrome-extension://pmfjbimdmchhbnneeidfognadeopoehp/image_loader_client.js';
-import {LoadImageRequest, LoadImageResponseStatus} from 'chrome-extension://pmfjbimdmchhbnneeidfognadeopoehp/load_image_request.js';
-import {assert, assertNotReached} from 'chrome://resources/ash/common/assert.js';
-
-import {unwrapEntry} from '../../../common/js/entry_utils.js';
-import {FileType} from '../../../common/js/file_type.js';
-import {getSanitizedScriptUrl} from '../../../common/js/trusted_script_url_policy_util.js';
-import {testSendMessage} from '../../../common/js/util.js';
-import {ThumbnailLoader} from '../thumbnail_loader.js';
-
-import {MetadataItem} from './metadata_item.js';
-import {MetadataProvider} from './metadata_provider.js';
-
-/** @final */
-export class ContentMetadataProvider extends MetadataProvider {
-  /**
-   * @param {!MessagePort=} opt_messagePort Message port overriding the default
-   *     worker port.
-   */
-  constructor(opt_messagePort) {
-    super(ContentMetadataProvider.PROPERTY_NAMES);
-
-    /**
-     * Pass all URLs to the metadata reader until we have a correct filter.
-     * @private @type {RegExp}
-     */
-    this.urlFilter_ = /.*/;
-
-    /**
-     * Initialization is not complete until the Worker sends back the
-     * 'initialized' message.  See below.
-     * @private @type {boolean}
-     */
-    this.initialized_ = false;
-
-    /**
-     * Map from Entry.toURL() to callback.
-     * Note that simultaneous requests for same url are handled in
-     * MetadataCache.
-     * @private @const @type {!Record<!string,
-     *     !Array<function(!MetadataItem):void>>}
-     */
-    this.callbacks_ = {};
-
-    /**
-     * Setup |this.disapatcher_|. Creates the Shared Worker if needed.
-     * @private @const @type {!MessagePort}
-     */
-    this.dispatcher_ = this.createSharedWorker_(opt_messagePort);
-    this.dispatcher_.onmessage = this.onMessage_.bind(this);
-    this.dispatcher_.onmessageerror = (error) => {
-      console.warn('ContentMetadataProvider worker msg error:', error);
-    };
-    this.dispatcher_.postMessage({verb: 'init'});
-    this.dispatcher_.start();
-  }
-
-  /**
-   * Returns |opt_messagePort| if given. Otherwise creates the Shared Worker
-   * and returns its message port.
-   * @param {!MessagePort=} opt_messagePort
-   * @private
-   * @return {!MessagePort}
-   * @suppress {checkTypes}: crbug.com/1150718
-   */
-  createSharedWorker_(opt_messagePort) {
-    if (opt_messagePort) {
-      return opt_messagePort;
-    }
-
-    const script = ContentMetadataProvider.getWorkerScript();
-
-    /** @type {!WorkerOptions} */
-    const options =
-        ContentMetadataProvider.loadAsModule_ ? {type: 'module'} : {};
-
-    // @ts-ignore: error TS2345: Argument of type 'TrustedScriptURL' is not
-    // assignable to parameter of type 'string | URL'.
-    const worker = new SharedWorker(getSanitizedScriptUrl(script), options);
-    worker.onerror = () => {
-      console.warn(
-          'Error to initialize the ContentMetadataProvider ' +
-          'SharedWorker: ' + script);
-    };
-    return worker.port;
-  }
-
-  /**
-   * Configures how the worker should be loaded.
-   *
-   * @param {string} scriptURL URL used to load the worker.
-   * @param {boolean=} isModule Indicate if the worker should be loaded as
-   *   module.
-   */
-  static configure(scriptURL, isModule) {
-    ContentMetadataProvider.workerScript_ = scriptURL;
-    ContentMetadataProvider.loadAsModule_ = !!isModule;
-  }
-
-  /** @public @return {string} */
-  static getWorkerScript() {
-    return ContentMetadataProvider.workerScript_ ?
-        ContentMetadataProvider.workerScript_ :
-        ContentMetadataProvider.DEFAULT_WORKER_SCRIPT_;
-  }
-
-  /**
-   * Converts content metadata from parsers to the internal format.
-   * @param {Object} metadata The content metadata.
-   * @return {!MetadataItem} Converted metadata.
-   */
-  static convertContentMetadata(metadata) {
-    const item = new MetadataItem();
-    // @ts-ignore: error TS7053: Element implicitly has an 'any' type because
-    // expression of type '"imageTransform"' can't be used to index type
-    // 'Object'.
-    item.contentImageTransform = metadata['imageTransform'];
-    // @ts-ignore: error TS7053: Element implicitly has an 'any' type because
-    // expression of type '"thumbnailTransform"' can't be used to index type
-    // 'Object'.
-    item.contentThumbnailTransform = metadata['thumbnailTransform'];
-    // @ts-ignore: error TS7053: Element implicitly has an 'any' type because
-    // expression of type '"thumbnailURL"' can't be used to index type 'Object'.
-    item.contentThumbnailUrl = metadata['thumbnailURL'];
-    // @ts-ignore: error TS7053: Element implicitly has an 'any' type because
-    // expression of type '"littleEndian"' can't be used to index type 'Object'.
-    item.exifLittleEndian = metadata['littleEndian'];
-    // @ts-ignore: error TS7053: Element implicitly has an 'any' type because
-    // expression of type '"ifd"' can't be used to index type 'Object'.
-    item.ifd = metadata['ifd'];
-    // @ts-ignore: error TS7053: Element implicitly has an 'any' type because
-    // expression of type '"height"' can't be used to index type 'Object'.
-    item.imageHeight = metadata['height'];
-    // @ts-ignore: error TS7053: Element implicitly has an 'any' type because
-    // expression of type '"width"' can't be used to index type 'Object'.
-    item.imageWidth = metadata['width'];
-    // @ts-ignore: error TS7053: Element implicitly has an 'any' type because
-    // expression of type '"mimeType"' can't be used to index type 'Object'.
-    item.mediaMimeType = metadata['mimeType'];
-    return item;
-  }
-
-  /** @override */
-  // @ts-ignore: error TS7006: Parameter 'requests' implicitly has an 'any'
-  // type.
-  get(requests) {
-    if (!requests.length) {
-      return Promise.resolve([]);
-    }
-
-    const promises = [];
-    for (let i = 0; i < requests.length; i++) {
-      // @ts-ignore: error TS7006: Parameter 'fulfill' implicitly has an 'any'
-      // type.
-      promises.push(new Promise(function(request, fulfill) {
-        // @ts-ignore: error TS2683: 'this' implicitly has type 'any' because it
-        // does not have a type annotation.
-        this.getImpl_(request.entry, request.names, fulfill);
-      }.bind(this, requests[i])));
-    }
-
-    return Promise.all(promises);
-  }
-
-  /**
-   * Fetches the entry metadata.
-   * @param {!Entry} entry File entry.
-   * @param {!Array<string>} names Requested metadata types.
-   * @param {function(!MetadataItem):void} callback MetadataItem callback. Note
-   *     this callback is called asynchronously.
-   * @private
-   */
-  // @ts-ignore: error TS6133: 'getImpl_' is declared but its value is never
-  // read.
-  getImpl_(entry, names, callback) {
-    if (entry.isDirectory) {
-      const cause = 'Directories do not have a thumbnail.';
-      const error = this.createError_(entry.toURL(), 'get', cause);
-      setTimeout(callback, 0, error);
-      return;
-    }
-
-    const type = FileType.getType(entry);
-
-    if (type && type.type === 'image') {
-      // Parse the image using the Worker image metadata parsers.
-      const url = entry.toURL();
-      // @ts-ignore: error TS7053: Element implicitly has an 'any' type because
-      // expression of type 'string' can't be used to index type '{}'.
-      if (this.callbacks_[url]) {
-        // @ts-ignore: error TS7053: Element implicitly has an 'any' type
-        // because expression of type 'string' can't be used to index type '{}'.
-        this.callbacks_[url].push(callback);
-      } else {
-        // @ts-ignore: error TS7053: Element implicitly has an 'any' type
-        // because expression of type 'string' can't be used to index type '{}'.
-        this.callbacks_[url] = [callback];
-        this.dispatcher_.postMessage({verb: 'request', arguments: [url]});
-      }
-      return;
-    }
-
-    if (type && type.type === 'raw' && names.includes('ifd')) {
-      // The RAW file ifd will be processed herein, so remove ifd from names.
-      names.splice(names.indexOf('ifd'), 1);
-
-      /**
-       * Creates an ifdError metadata item: when reading the fileEntry failed
-       * or extracting its ifd data failed.
-       * @param {!Entry} fileEntry
-       * @param {string} error
-       * @return {!MetadataItem}
-       */
-      function createIfdError(fileEntry, error) {
-        const url = fileEntry.toURL();
-        const step = 'read file entry';
-        const item = new MetadataItem();
-        // @ts-ignore: error TS2339: Property 'ifdError' does not exist on type
-        // 'MetadataItem'.
-        item.ifdError = new ContentMetadataProvider.Error(url, step, error);
-        return item;
-      }
-
-      new Promise((resolve, reject) => {
-        // @ts-ignore: error TS2339: Property 'file' does not exist on type
-        // 'FileSystemEntry'.
-        entry.file(
-            // @ts-ignore: error TS7006: Parameter 'file' implicitly has an
-            // 'any' type.
-            file => {
-              const request = LoadImageRequest.createForUrl(entry.toURL());
-              request.maxWidth = ThumbnailLoader.THUMBNAIL_MAX_WIDTH;
-              request.maxHeight = ThumbnailLoader.THUMBNAIL_MAX_HEIGHT;
-              request.timestamp = file.lastModified;
-              request.cache = true;
-              request.priority = 0;
-              ImageLoaderClient.getInstance().load(request, resolve);
-            },
-            // @ts-ignore: error TS7006: Parameter 'error' implicitly has an
-            // 'any' type.
-            error => {
-              callback(createIfdError(entry, error.toString()));
-              reject();
-            });
-      }).then(result => {
-        if (result.status === LoadImageResponseStatus.SUCCESS) {
-          const item = new MetadataItem();
-          if (result.ifd) {
-            item.ifd = /** @type {!Object} */ (JSON.parse(result.ifd));
-          }
-          callback(item);
-        } else {
-          callback(createIfdError(entry, 'raw file has no ifd data'));
-        }
-      });
-
-      if (!names.length) {
-        return;
-      }
-    }
-
-    const fileEntry = /** @type {!FileEntry} */ (unwrapEntry(entry));
-    this.getContentMetadata_(fileEntry, names).then(callback);
-  }
-
-  /**
-   * Gets the content metadata for a file entry consisting of the content mime
-   * type. For audio and video file content mime types, additional metadata is
-   * extacted if requested, such as metadata tags and images.
-   *
-   * @param {!FileEntry} entry File entry.
-   * @param {!Array<string>} names Requested metadata types.
-   * @return {!Promise<!MetadataItem>} Promise that resolves with the content
-   *     metadata of the file entry.
-   * @private
-   */
-  getContentMetadata_(entry, names) {
-    /**
-     * First step is to determine the sniffed content mime type of |entry|.
-     * @const @type {!Promise<!MetadataItem>}
-     */
-    // @ts-ignore: error TS6133: 'reject' is declared but its value is never
-    // read.
-    const getContentMimeType = new Promise((resolve, reject) => {
-      chrome.fileManagerPrivate.getContentMimeType(entry, resolve);
-    }).then(mimeType => {
-      if (chrome.runtime.lastError) {
-        const error = chrome.runtime.lastError.toString();
-        return this.createError_(entry.toURL(), 'sniff mime type', error);
-      }
-      const item = new MetadataItem();
-      item.contentMimeType = mimeType;
-      item.mediaMimeType = mimeType;
-      return item;
-    });
-
-    /**
-     * Once the content mime type sniff step is done, search |names| for any
-     * remaining media metadata to extract from the file. Note mediaMimeType
-     * is excluded since it is used for the sniff step.
-     * @param {!Array<string>} names Requested metadata types.
-     * @param {(string|undefined)} type File entry content mime type.
-     * @return {?boolean} Media metadata type: false for metadata tags, true
-     *    for metadata tags and images. A null return means there is no more
-     *    media metadata that needs to be extracted.
-     */
-    function getMediaMetadataType(names, type) {
-      if (!type || !names.length) {
-        return null;
-      } else if (!type.startsWith('audio/') && !type.startsWith('video/')) {
-        return null;  // Only audio and video are supported.
-      } else if (names.includes('contentThumbnailUrl')) {
-        return true;  // Metadata tags and images.
-      } else if (names.find((name) =>
-          name.startsWith('media') && name !== 'mediaMimeType')) {
-        return false;  // Metadata tags only.
-      }
-      return null;
-    }
-
-    return getContentMimeType.then(item => {
-      const extract = getMediaMetadataType(names, item.contentMimeType);
-      if (extract === null) {
-        return item;  // done: no more media metadata to extract.
-      }
-      // @ts-ignore: error TS6133: 'reject' is declared but its value is never
-      // read.
-      return new Promise((resolve, reject) => {
-        const contentMimeType = assert(item.contentMimeType);
-        chrome.fileManagerPrivate.getContentMetadata(
-            // @ts-ignore: error TS2345: Argument of type 'string | undefined'
-            // is not assignable to parameter of type 'string'.
-            entry, contentMimeType, !!extract, resolve);
-      }).then(metadata => {
-        if (chrome.runtime.lastError) {
-          const error = chrome.runtime.lastError.toString();
-          return this.createError_(entry.toURL(), 'content metadata', error);
-        }
-        return this.convertMediaMetadataToMetadataItem_(entry, metadata);
-      }).catch((_, error = 'Conversion failed') => {
-        return this.createError_(entry.toURL(), 'convert metadata', error);
-      });
-    });
-  }
-
-  /**
-   * Dispatches a message from a metadata reader to the appropriate on* method.
-   * @param {Object} event The event.
-   * @private
-   */
-  onMessage_(event) {
-    // @ts-ignore: error TS2339: Property 'data' does not exist on type
-    // 'Object'.
-    const data = event.data;
-    switch (data.verb) {
-      case 'initialized':
-        this.onInitialized_(data.arguments[0]);
-        break;
-      case 'result':
-        this.onResult_(
-            data.arguments[0],
-            data.arguments[1] ? ContentMetadataProvider.convertContentMetadata(
-                                    data.arguments[1]) :
-                                new MetadataItem());
-        break;
-      case 'error':
-        const error = this.createError_(
-            data.arguments[0], data.arguments[1], data.arguments[2]);
-        this.onResult_(data.arguments[0], error);
-        break;
-      case 'log':
-        this.onLog_(data.arguments[0]);
-        break;
-      default:
-        assertNotReached();
-        break;
-    }
-  }
-
-  /**
-   * Handles the 'initialized' message from the metadata Worker.
-   * @param {RegExp} regexp Regexp of supported urls.
-   * @private
-   */
-  onInitialized_(regexp) {
-    this.urlFilter_ = regexp;
-
-    // Tests can monitor for this state with
-    // ExtensionTestMessageListener listener("worker-initialized");
-    // ASSERT_TRUE(listener.WaitUntilSatisfied());
-    // Automated tests need to wait for this, otherwise we crash in
-    // browser_test cleanup because the worker process still has
-    // URL requests in-flight.
-    testSendMessage('worker-initialized');
-    this.initialized_ = true;
-  }
-
-  /**
-   * Handles the 'result' message from the metadata Worker.
-   * @param {string} url File url.
-   * @param {!MetadataItem} metadataItem The metadata item.
-   * @private
-   */
-  onResult_(url, metadataItem) {
-    // @ts-ignore: error TS7053: Element implicitly has an 'any' type because
-    // expression of type 'string' can't be used to index type '{}'.
-    const callbacks = this.callbacks_[url];
-    // @ts-ignore: error TS7053: Element implicitly has an 'any' type because
-    // expression of type 'string' can't be used to index type '{}'.
-    delete this.callbacks_[url];
-    // @ts-ignore: error TS18048: 'callbacks' is possibly 'undefined'.
-    for (let i = 0; i < callbacks.length; i++) {
-      // @ts-ignore: error TS2722: Cannot invoke an object which is possibly
-      // 'undefined'.
-      callbacks[i](metadataItem);
-    }
-  }
-
-  /**
-   * Handles the 'log' message from the metadata Worker.
-   * @param {Array<*>} arglist Log arguments.
-   * @private
-   */
-  onLog_(arglist) {
-    console.log.apply(
-        console, ['ContentMetadataProvider log:'].concat(arglist));
-  }
-
-  /**
-   * Converts fileManagerPrivate.MediaMetadata |metadata| to a MetadataItem.
-   * @param {!FileEntry} entry File entry.
-   * @param {!chrome.fileManagerPrivate.MediaMetadata} metadata The metadata.
-   * @return {!Promise<!MetadataItem>} Promise that resolves with the
-   *    converted metadata item.
-   * @private
-   */
-  convertMediaMetadataToMetadataItem_(entry, metadata) {
-    // @ts-ignore: error TS6133: 'reject' is declared but its value is never
-    // read.
-    return new Promise((resolve, reject) => {
-      if (!metadata) {
-        resolve(this.createError_(
-            entry.toURL(), 'metadata result', 'Failed to parse metadata'));
-        return;
-      }
-
-      const item = new MetadataItem();
-      const mimeType = metadata['mimeType'];
-      item.contentMimeType = mimeType;
-      item.mediaMimeType = mimeType;
-
-      const trans = {scaleX: 1, scaleY: 1, rotate90: 0};
-      if (metadata.rotation) {
-        switch (metadata.rotation) {
-          case 0:
-            break;
-          case 90:
-            trans.rotate90 = 1;
-            break;
-          case 180:
-            trans.scaleX *= -1;
-            trans.scaleY *= -1;
-            break;
-          case 270:
-            trans.rotate90 = 1;
-            trans.scaleX *= -1;
-            trans.scaleY *= -1;
-            break;
-          default:
-            console.error('Unknown rotation angle: ', metadata.rotation);
-        }
-      }
-      if (metadata.rotation) {
-        item.contentImageTransform = item.contentThumbnailTransform = trans;
-      }
-
-      item.imageHeight = metadata['height'];
-      item.imageWidth = metadata['width'];
-      item.mediaAlbum = metadata['album'];
-      item.mediaArtist = metadata['artist'];
-      item.mediaDuration = metadata['duration'];
-      item.mediaGenre = metadata['genre'];
-      item.mediaTitle = metadata['title'];
-
-      if (metadata['track']) {
-        item.mediaTrack = '' + metadata['track'];
-      }
-      if (metadata.rawTags) {
-        metadata.rawTags.forEach(entry => {
-          if (entry.type === 'mp3') {
-            // @ts-ignore: error TS7053: Element implicitly has an 'any' type
-            // because expression of type '"date"' can't be used to index type
-            // 'Object'.
-            if (entry.tags['date']) {
-              // @ts-ignore: error TS7053: Element implicitly has an 'any' type
-              // because expression of type '"date"' can't be used to index type
-              // 'Object'.
-              item.mediaYearRecorded = entry.tags['date'];
-            }
-            // It is possible that metadata['track'] is undefined but this is
-            // defined.
-            // @ts-ignore: error TS7053: Element implicitly has an 'any' type
-            // because expression of type '"track"' can't be used to index type
-            // 'Object'.
-            if (entry.tags['track']) {
-              // @ts-ignore: error TS7053: Element implicitly has an 'any' type
-              // because expression of type '"track"' can't be used to index
-              // type 'Object'.
-              item.mediaTrack = entry.tags['track'];
-            }
-          }
-        });
-      }
-
-      if (metadata.attachedImages && metadata.attachedImages.length > 0) {
-        // @ts-ignore: error TS2532: Object is possibly 'undefined'.
-        item.contentThumbnailUrl = metadata.attachedImages[0].data;
-      }
-
-      resolve(item);
-    });
-  }
-
-  /**
-   * Returns an 'error' MetadataItem.
-   * @param {string} url File entry.
-   * @param {string} step Step that failed.
-   * @param {string} cause Error cause.
-   * @return {!MetadataItem} Error metadata
-   * @private
-   */
-  createError_(url, step, cause) {
-    const error = new ContentMetadataProvider.Error(url, step, cause);
-    const item = new MetadataItem();
-    item.contentImageTransformError = error;
-    item.contentThumbnailTransformError = error;
-    item.contentThumbnailUrlError = error;
-    return item;
-  }
-}
-
-/**
- * Content metadata provider error.
- */
-ContentMetadataProvider.Error = class extends Error {
-  /**
-   * @param {string} url File Entry.
-   * @param {string} step Step that failed.
-   * @param {string} cause Error cause.
-   */
-  constructor(url, step, cause) {
-    super(cause);
-
-    /** @public @const @type {string} */
-    this.url = url;
-
-    /** @public @const @type {string} */
-    this.step = step;
-
-    /** @public @const @type {string} */
-    this.errorDescription = cause;
-  }
-};
-
-/** @public @const @type {!Array<string>} */
-ContentMetadataProvider.PROPERTY_NAMES = [
-  'contentImageTransform',
-  'contentThumbnailTransform',
-  'contentThumbnailUrl',
-  'exifLittleEndian',
-  'ifd',
-  'imageHeight',
-  'imageWidth',
-  'mediaAlbum',
-  'mediaArtist',
-  'mediaDuration',
-  'mediaGenre',
-  'mediaMimeType',
-  'mediaTitle',
-  'mediaTrack',
-  'mediaYearRecorded',
-];
-
-/**
- * The metadata Worker script URL.
- * @const @private @type {string}
- */
-// @ts-ignore: error TS2341: Property 'DEFAULT_WORKER_SCRIPT_' is private and
-// only accessible within class 'ContentMetadataProvider'.
-ContentMetadataProvider.DEFAULT_WORKER_SCRIPT_ =
-    'foreground/js/metadata/metadata_dispatcher.js';
-
-/**
- * Worker script URL that is overwritten by client code.
- * @private @type {?string}
- */
-// @ts-ignore: error TS2341: Property 'workerScript_' is private and only
-// accessible within class 'ContentMetadataProvider'.
-ContentMetadataProvider.workerScript_ = null;
-
-/**
- * Sets if the SharedWorker should start as a JS Module.
- * @private @type {boolean}
- */
-// @ts-ignore: error TS2341: Property 'loadAsModule_' is private and only
-// accessible within class 'ContentMetadataProvider'.
-ContentMetadataProvider.loadAsModule_ = true;
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider.ts b/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider.ts
new file mode 100644
index 0000000..8e574c6
--- /dev/null
+++ b/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider.ts
@@ -0,0 +1,457 @@
+// Copyright 2015 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {ImageLoaderClient} from 'chrome-extension://pmfjbimdmchhbnneeidfognadeopoehp/image_loader_client.js';
+import {LoadImageRequest, type LoadImageResponse, LoadImageResponseStatus} from 'chrome-extension://pmfjbimdmchhbnneeidfognadeopoehp/load_image_request.js';
+import {assert, assertNotReached} from 'chrome://resources/js/assert.js';
+
+import {unwrapEntry} from '../../../common/js/entry_utils.js';
+import {FileType} from '../../../common/js/file_type.js';
+import {getSanitizedScriptUrl} from '../../../common/js/trusted_script_url_policy_util.js';
+import {testSendMessage} from '../../../common/js/util.js';
+import {ThumbnailLoader} from '../thumbnail_loader.js';
+
+import {MetadataItem, ParserMetadata} from './metadata_item.js';
+import {MetadataProvider} from './metadata_provider.js';
+import type {MetadataRequest} from './metadata_request.js';
+
+const WORKER_SCRIPT = 'foreground/js/metadata/metadata_dispatcher.js';
+
+/** @final */
+export class ContentMetadataProvider extends MetadataProvider {
+  static readonly PROPERTY_NAMES = [
+    'contentImageTransform',
+    'contentThumbnailTransform',
+    'contentThumbnailUrl',
+    'exifLittleEndian',
+    'ifd',
+    'imageHeight',
+    'imageWidth',
+    'mediaAlbum',
+    'mediaArtist',
+    'mediaDuration',
+    'mediaGenre',
+    'mediaMimeType',
+    'mediaTitle',
+    'mediaTrack',
+    'mediaYearRecorded',
+  ];
+
+  /**
+   * Map from Entry.toURL() to callback.
+   * Note that simultaneous requests for same url are handled in MetadataCache.
+   */
+  private callbacks_: Record<string, Array<(item: MetadataItem) => void>> = {};
+
+  private readonly dispatcher_: MessagePort;
+
+  /**
+   * @param messagePort Message port overriding the default worker port.
+   */
+  constructor(messagePort?: MessagePort) {
+    super(ContentMetadataProvider.PROPERTY_NAMES);
+
+    // Set up |this.disapatcher_|. Creates the Shared Worker if needed.
+    this.dispatcher_ = this.createSharedWorker_(messagePort);
+    this.dispatcher_.onmessage = this.onMessage_.bind(this);
+    this.dispatcher_.onmessageerror = (error) => {
+      console.warn('ContentMetadataProvider worker msg error:', error);
+    };
+    this.dispatcher_.postMessage({verb: 'init'});
+    this.dispatcher_.start();
+  }
+
+  /**
+   * Returns |messagePort| if given. Otherwise creates the Shared Worker
+   * and returns its message port.
+   */
+  private createSharedWorker_(messagePort?: MessagePort): MessagePort {
+    if (messagePort) {
+      return messagePort;
+    }
+
+    const options: WorkerOptions = {type: 'module'};
+    const worker = new SharedWorker(
+        getSanitizedScriptUrl(WORKER_SCRIPT) as unknown as string, options);
+    worker.onerror = () => {
+      console.warn('Error to initialize the ContentMetadataProvider');
+    };
+    return worker.port;
+  }
+
+  /**
+   * Converts content metadata from parsers to the internal format.
+   * @param metadata The content metadata.
+   * @return Converted metadata.
+   */
+  static convertContentMetadata(metadata: ParserMetadata): MetadataItem {
+    const item = new MetadataItem();
+    item.contentImageTransform = metadata['imageTransform'];
+    item.contentThumbnailTransform = metadata['thumbnailTransform'];
+    item.contentThumbnailUrl = metadata['thumbnailURL'];
+    item.exifLittleEndian = metadata['littleEndian'];
+    item.ifd = metadata['ifd'];
+    item.imageHeight = metadata['height'];
+    item.imageWidth = metadata['width'];
+    item.mediaMimeType = metadata['mimeType'];
+    return item;
+  }
+
+  override get(requests: MetadataRequest[]): Promise<MetadataItem[]> {
+    if (!requests.length) {
+      return Promise.resolve([]);
+    }
+
+    const promises = [];
+    for (const request of requests) {
+      promises.push(new Promise<MetadataItem>(fulfill => {
+        this.getImpl_(request.entry, request.names, fulfill);
+      }));
+    }
+
+    return Promise.all(promises);
+  }
+
+  /**
+   * Fetches the entry metadata.
+   * @param entry File entry.
+   * @param names Requested metadata types.
+   * @param callback MetadataItem callback. Note
+   *     this callback is called asynchronously.
+   */
+  private getImpl_(
+      entry: Entry, names: string[], callback: (item: MetadataItem) => void) {
+    if (entry.isDirectory) {
+      const cause = 'Directories do not have a thumbnail.';
+      const error = this.createError_(entry.toURL(), 'get', cause);
+      setTimeout(callback, 0, error);
+      return;
+    }
+
+    const type = FileType.getType(entry);
+
+    if (type && type.type === 'image') {
+      // Parse the image using the Worker image metadata parsers.
+      const url = entry.toURL();
+      const urlCallbacks = this.callbacks_[url];
+      if (urlCallbacks) {
+        urlCallbacks.push(callback);
+      } else {
+        this.callbacks_[url] = [callback];
+        this.dispatcher_.postMessage({verb: 'request', arguments: [url]});
+      }
+      return;
+    }
+
+    if (type && type.type === 'raw' && names.includes('ifd')) {
+      // The RAW file ifd will be processed herein, so remove ifd from names.
+      names.splice(names.indexOf('ifd'), 1);
+
+      /**
+       * Creates an ifdError metadata item: when reading the fileEntry failed
+       * or extracting its ifd data failed.
+       */
+      function createIfdError(fileEntry: Entry, error: string): MetadataItem {
+        const url = fileEntry.toURL();
+        const step = 'read file entry';
+        const item = new MetadataItem();
+        item.ifdError = new ContentMetadataProviderError(url, step, error);
+        return item;
+      }
+
+      new Promise<LoadImageResponse>((resolve, reject) => {
+        (entry as FileEntry)
+            .file(
+                file => {
+                  const request = LoadImageRequest.createForUrl(entry.toURL());
+                  request.maxWidth = ThumbnailLoader.THUMBNAIL_MAX_WIDTH;
+                  request.maxHeight = ThumbnailLoader.THUMBNAIL_MAX_HEIGHT;
+                  request.timestamp = file.lastModified;
+                  request.cache = true;
+                  request.priority = 0;
+                  ImageLoaderClient.getInstance().load(request, resolve);
+                },
+                error => {
+                  callback(createIfdError(entry, error.toString()));
+                  reject();
+                });
+      }).then(result => {
+        if (result.status === LoadImageResponseStatus.SUCCESS) {
+          const item = new MetadataItem();
+          if (result.ifd) {
+            item.ifd = JSON.parse(result.ifd);
+          }
+          callback(item);
+        } else {
+          callback(createIfdError(entry, 'raw file has no ifd data'));
+        }
+      });
+
+      if (!names.length) {
+        return;
+      }
+    }
+
+    const fileEntry = unwrapEntry(entry) as FileEntry;
+    this.getContentMetadata_(fileEntry, names).then(callback);
+  }
+
+  /**
+   * Gets the content metadata for a file entry consisting of the content mime
+   * type. For audio and video file content mime types, additional metadata is
+   * extacted if requested, such as metadata tags and images.
+   *
+   * @param entry File entry.
+   * @param names Requested metadata types.
+   * @return Promise that resolves with the content
+   *     metadata of the file entry.
+   */
+  private getContentMetadata_(entry: FileEntry, names: string[]):
+      Promise<MetadataItem> {
+    /**
+     * First step is to determine the sniffed content mime type of |entry|.
+     * @const
+     */
+    const getContentMimeType =
+        new Promise<string>((resolve) => {
+          chrome.fileManagerPrivate.getContentMimeType(entry, resolve);
+        }).then(mimeType => {
+          if (chrome.runtime.lastError) {
+            const error = chrome.runtime.lastError.toString();
+            return this.createError_(entry.toURL(), 'sniff mime type', error);
+          }
+          const item = new MetadataItem();
+          item.contentMimeType = mimeType;
+          item.mediaMimeType = mimeType;
+          return item;
+        });
+
+    /**
+     * Once the content mime type sniff step is done, search |names| for any
+     * remaining media metadata to extract from the file. Note mediaMimeType
+     * is excluded since it is used for the sniff step.
+     * @param names Requested metadata types.
+     * @param type File entry content mime type.
+     * @return Media metadata type: false for metadata tags, true
+     *    for metadata tags and images. A null return means there is no more
+     *    media metadata that needs to be extracted.
+     */
+    function getMediaMetadataType(
+        names: string[], type: (string|undefined)): null|boolean {
+      if (!type || !names.length) {
+        return null;
+      } else if (!type.startsWith('audio/') && !type.startsWith('video/')) {
+        return null;  // Only audio and video are supported.
+      } else if (names.includes('contentThumbnailUrl')) {
+        return true;  // Metadata tags and images.
+      } else if (names.find(
+                     (name) => name.startsWith('media') &&
+                         name !== 'mediaMimeType')) {
+        return false;  // Metadata tags only.
+      }
+      return null;
+    }
+
+    return getContentMimeType.then(item => {
+      const extract = getMediaMetadataType(names, item.contentMimeType);
+      if (extract === null) {
+        return item;  // done: no more media metadata to extract.
+      }
+      return new Promise<chrome.fileManagerPrivate.MediaMetadata>((resolve) => {
+               const contentMimeType = item.contentMimeType;
+               assert(contentMimeType);
+               chrome.fileManagerPrivate.getContentMetadata(
+                   entry, contentMimeType, !!extract, resolve);
+             })
+          .then(metadata => {
+            if (chrome.runtime.lastError) {
+              const error = chrome.runtime.lastError.toString();
+              return this.createError_(
+                  entry.toURL(), 'content metadata', error);
+            }
+            return this.convertMediaMetadataToMetadataItem_(entry, metadata);
+          })
+          .catch((_, error = 'Conversion failed') => {
+            return this.createError_(entry.toURL(), 'convert metadata', error);
+          });
+    });
+  }
+
+  /**
+   * Dispatches a message from a metadata reader to the appropriate on* method.
+   * @param event The event.
+   */
+  private onMessage_(event: {data: {verb: string, arguments: unknown[]}}) {
+    const data = event.data;
+    switch (data.verb) {
+      case 'initialized':
+        this.onInitialized_();
+        break;
+      case 'result':
+        const [fileURL, metadata] = data.arguments as [string, ParserMetadata];
+        this.onResult_(
+            fileURL,
+            metadata ?
+                ContentMetadataProvider.convertContentMetadata(metadata) :
+                new MetadataItem());
+        break;
+      case 'error':
+        const [url, step, cause] = data.arguments as [string, string, string];
+        const error = this.createError_(url, step, cause);
+        this.onResult_(url, error);
+        break;
+      case 'log':
+        const [message] = data.arguments as [string, ];
+        this.onLog_(message);
+        break;
+      default:
+        assertNotReached();
+    }
+  }
+
+  /**
+   * Handles the 'initialized' message from the metadata Worker.
+   */
+  private onInitialized_() {
+    // Tests can monitor for this state with
+    // ExtensionTestMessageListener listener("worker-initialized");
+    // ASSERT_TRUE(listener.WaitUntilSatisfied());
+    // Automated tests need to wait for this, otherwise we crash in
+    // browser_test cleanup because the worker process still has
+    // URL requests in-flight.
+    testSendMessage('worker-initialized');
+  }
+
+  /**
+   * Handles the 'result' message from the metadata Worker.
+   * @param url File url.
+   * @param metadataItem The metadata item.
+   */
+  private onResult_(url: string, metadataItem: MetadataItem) {
+    const callbacks = this.callbacks_[url]!;
+    delete this.callbacks_[url];
+    for (const callback of callbacks) {
+      callback(metadataItem);
+    }
+  }
+
+  /**
+   * Handles the 'log' message from the metadata Worker.
+   * @param arglist Log arguments.
+   */
+  private onLog_(message: string) {
+    console.log('ContentMetadataProvider log:' + message);
+  }
+
+  /**
+   * Converts fileManagerPrivate.MediaMetadata |metadata| to a MetadataItem.
+   * @param entry File entry.
+   * @param metadata The metadata.
+   * @return Promise that resolves with the
+   *    converted metadata item.
+   */
+  private convertMediaMetadataToMetadataItem_(
+      entry: FileEntry, metadata: chrome.fileManagerPrivate.MediaMetadata):
+      Promise<MetadataItem> {
+    return new Promise((resolve) => {
+      if (!metadata) {
+        resolve(this.createError_(
+            entry.toURL(), 'metadata result', 'Failed to parse metadata'));
+        return;
+      }
+
+      const item = new MetadataItem();
+      const mimeType = metadata['mimeType'];
+      item.contentMimeType = mimeType;
+      item.mediaMimeType = mimeType;
+
+      const trans = {scaleX: 1, scaleY: 1, rotate90: 0};
+      if (metadata.rotation) {
+        switch (metadata.rotation) {
+          case 0:
+            break;
+          case 90:
+            trans.rotate90 = 1;
+            break;
+          case 180:
+            trans.scaleX *= -1;
+            trans.scaleY *= -1;
+            break;
+          case 270:
+            trans.rotate90 = 1;
+            trans.scaleX *= -1;
+            trans.scaleY *= -1;
+            break;
+          default:
+            console.error('Unknown rotation angle: ', metadata.rotation);
+        }
+      }
+      if (metadata.rotation) {
+        item.contentImageTransform = item.contentThumbnailTransform = trans;
+      }
+
+      item.imageHeight = metadata['height'];
+      item.imageWidth = metadata['width'];
+      item.mediaAlbum = metadata['album'];
+      item.mediaArtist = metadata['artist'];
+      item.mediaDuration = metadata['duration'];
+      item.mediaGenre = metadata['genre'];
+      item.mediaTitle = metadata['title'];
+
+      if (metadata['track']) {
+        item.mediaTrack = '' + metadata['track'];
+      }
+      if (metadata.rawTags) {
+        metadata.rawTags.forEach(entry => {
+          const tags = entry.tags as Record<string, string>;
+          if (entry.type === 'mp3') {
+            if (tags['date']) {
+              item.mediaYearRecorded = tags['date'];
+            }
+            // It is possible that metadata['track'] is undefined but this is
+            // defined.
+            if (tags['track']) {
+              item.mediaTrack = tags['track'];
+            }
+          }
+        });
+      }
+
+      if (metadata.attachedImages && metadata.attachedImages.length > 0) {
+        item.contentThumbnailUrl = metadata.attachedImages[0]!.data;
+      }
+
+      resolve(item);
+    });
+  }
+
+  /**
+   * Returns an 'error' MetadataItem.
+   * @param url File entry.
+   * @param step Step that failed.
+   * @param cause Error cause.
+   * @return Error metadata
+   */
+  private createError_(url: string, step: string, cause: string): MetadataItem {
+    const error = new ContentMetadataProviderError(url, step, cause);
+    const item = new MetadataItem();
+    item.contentImageTransformError = error;
+    item.contentThumbnailTransformError = error;
+    item.contentThumbnailUrlError = error;
+    return item;
+  }
+}
+
+class ContentMetadataProviderError extends Error {
+  /**
+   * @param url File Entry.
+   * @param step Step that failed.
+   * @param errorDescription Error cause.
+   */
+  constructor(
+      public readonly url: string, public readonly step: string,
+      public readonly errorDescription: string) {
+    super(errorDescription);
+  }
+}
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider_unittest.js b/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider_unittest.ts
similarity index 70%
rename from ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider_unittest.js
rename to ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider_unittest.ts
index 473e22d..8bbc43f 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider_unittest.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider_unittest.ts
@@ -9,10 +9,9 @@
 import {ContentMetadataProvider} from './content_metadata_provider.js';
 import {MetadataRequest} from './metadata_request.js';
 
-// @ts-ignore: error TS7006: Parameter 'dataUrl' implicitly has an 'any' type.
-function makeFileEntryFromDataURL(name, dataUrl) {
-  const mimeString = dataUrl.split(',')[0].split(':')[1].split(';')[0];
-  const data = atob(dataUrl.split('base64,')[1]);
+function makeFileEntryFromDataURL(name: string, dataUrl: string) {
+  const mimeString = dataUrl.split(',')[0]!.split(':')[1]!.split(';')[0];
+  const data = atob(dataUrl.split('base64,')[1]!);
   const dataArray = [];
   for (let i = 0; i < data.length; ++i) {
     dataArray.push(data.charCodeAt(i));
@@ -23,10 +22,8 @@
     name: name,
     isDirectory: false,
     url: dataUrl,
-    // @ts-ignore: error TS7006: Parameter 'callback' implicitly has an 'any'
-    // type.
-    file: function(callback) {
-      callback(blob);
+    file: function(callback: FileCallback) {
+      callback(blob as File);
     },
     toURL: function() {
       return dataUrl;
@@ -69,15 +66,12 @@
 
 const entryB = makeFileEntryFromDataURL('empty.jpg', 'data:image/jpeg;base64,');
 
-/** @param {()=>void} callback */
-export function testExternalMetadataProviderBasic(callback) {
+export function testExternalMetadataProviderBasic(callback: () => void) {
   // Mocking SharedWorker's port.
-  const port = /** @type {!MessagePort} */ ({
+  const port = {
     postMessage: function(message) {
       if (message.verb === 'request') {
-        // @ts-ignore: error TS2721: Cannot invoke an object which is possibly
-        // 'null'.
-        port.onmessage(/** @type {!MessageEvent} */ ({
+        port.onmessage!({
           data: {
             verb: 'result',
             arguments: [
@@ -88,11 +82,11 @@
               },
             ],
           },
-        }));
+        } as MessageEvent);
       }
     },
     start: function() {},
-  });
+  } as MessagePort;
 
   // TODO(ryoh): chrome.mediaGalleries API is not available in unit tests.
   const provider = new ContentMetadataProvider(port);
@@ -100,28 +94,22 @@
       provider
           .get([
             new MetadataRequest(
-                // @ts-ignore: error TS2345: Argument of type '{ name: any;
-                // isDirectory: boolean; url: any; file: (callback: any) =>
-                // void; toURL: () => any; }' is not assignable to parameter of
-                // type 'FileSystemEntry'.
-                entryA, ['contentThumbnailUrl', 'contentThumbnailTransform']),
+                entryA as unknown as FileSystemEntry,
+                ['contentThumbnailUrl', 'contentThumbnailTransform']),
             new MetadataRequest(
-                // @ts-ignore: error TS2345: Argument of type '{ name: any;
-                // isDirectory: boolean; url: any; file: (callback: any) =>
-                // void; toURL: () => any; }' is not assignable to parameter of
-                // type 'FileSystemEntry'.
-                entryB, ['contentThumbnailUrl', 'contentThumbnailTransform']),
+                entryB as unknown as FileSystemEntry,
+                ['contentThumbnailUrl', 'contentThumbnailTransform']),
           ])
           .then(results => {
             assertEquals(2, results.length);
-            assertEquals(entryA.url + ',url', results[0].contentThumbnailUrl);
+            assertEquals(entryA.url + ',url', results[0]!.contentThumbnailUrl);
             assertEquals(
                 entryA.url + ',transform',
-                results[0].contentThumbnailTransform);
-            assertEquals(entryB.url + ',url', results[1].contentThumbnailUrl);
+                results[0]!.contentThumbnailTransform);
+            assertEquals(entryB.url + ',url', results[1]!.contentThumbnailUrl);
             assertEquals(
                 entryB.url + ',transform',
-                results[1].contentThumbnailTransform);
+                results[1]!.contentThumbnailTransform);
           }),
       callback);
 }
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/metadata_dispatcher.js b/ui/file_manager/file_manager/foreground/js/metadata/metadata_dispatcher.js
index 8474f479..e9b9d0a2 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/metadata_dispatcher.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata/metadata_dispatcher.js
@@ -69,6 +69,8 @@
   init_() {
     // Inform our owner that we're done initializing.
     // If we need to pass more data back, we can add it to the param array.
+    // TODO(cleanup): parserRegexp_ looks unused in content_metadata_provider
+    // and in this file, too.
     this.postMessage('initialized', [this.parserRegexp_]);
     this.vlog('initialized with URL filter ' + this.parserRegexp_);
   }
@@ -103,6 +105,9 @@
   // @ts-ignore: error TS6133: 'var_args' is declared but its value is never
   // read.
   error(var_args) {
+    // TODO(cleanup): Strictly type these arguments to the [url, step, cause]
+    // format that ContentMetadataProvider expects.
+
     // @ts-ignore: error TS2345: Argument of type 'IArguments' is not assignable
     // to parameter of type 'unknown[]'.
     const ary = Array.apply(null, arguments);
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/metadata_item.ts b/ui/file_manager/file_manager/foreground/js/metadata/metadata_item.ts
index 299cd8d8..db2dc64 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/metadata_item.ts
+++ b/ui/file_manager/file_manager/foreground/js/metadata/metadata_item.ts
@@ -144,6 +144,8 @@
    */
   ifd?: object;
 
+  ifdError?: Error;
+
   exifLittleEndian?: boolean;
 
   canCopy?: boolean;
@@ -207,3 +209,14 @@
    */
   syncCompletedTime?: number;
 }
+
+export class ParserMetadata {
+  imageTransform?: ImageTransformation;
+  thumbnailTransform?: ImageTransformation;
+  thumbnailURL?: string;
+  littleEndian?: boolean;
+  ifd?: object;
+  height?: number;
+  width?: number;
+  mimeType?: string;
+}
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/metadata_parser.js b/ui/file_manager/file_manager/foreground/js/metadata/metadata_parser.js
index 5ebf802..be1e87f 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/metadata_parser.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata/metadata_parser.js
@@ -97,6 +97,8 @@
     };
     fileReader.readAsArrayBuffer(file.slice(begin, end));
   }
+
+  // TODO(cleanup): Add parse() abstract method which fills in a ParserMetadata.
 }
 
 /**
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/multi_metadata_provider_unittest.js b/ui/file_manager/file_manager/foreground/js/metadata/multi_metadata_provider_unittest.js
index 2a42da0..3c40d04b 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/multi_metadata_provider_unittest.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata/multi_metadata_provider_unittest.js
@@ -91,10 +91,18 @@
             return Promise.resolve([]);
           }
           assertEquals(2, requests.length);
-          assertEquals('filesystem://A', requests[0].entry.toURL());
-          assertEquals('filesystem://B', requests[1].entry.toURL());
-          assertArrayEquals(['contentThumbnailUrl'], requests[0].names);
-          assertArrayEquals(['contentThumbnailUrl'], requests[1].names);
+          assertEquals(
+              'filesystem://A',
+              /** @type {!MetadataRequest} */ (requests[0]).entry.toURL());
+          assertEquals(
+              'filesystem://B',
+              /** @type {!MetadataRequest} */ (requests[1]).entry.toURL());
+          assertArrayEquals(
+              ['contentThumbnailUrl'],
+              /** @type {!MetadataRequest} */ (requests[0]).names);
+          assertArrayEquals(
+              ['contentThumbnailUrl'],
+              /** @type {!MetadataRequest} */ (requests[1]).names);
           return Promise.resolve([
             {contentThumbnailUrl: 'THUMBNAIL_URL_A'},
             {contentThumbnailUrl: 'THUMBNAIL_URL_B'},
@@ -172,7 +180,9 @@
             'filesystem://C': {imageWidth: 300},
           };
           assertEquals(1, requests.length);
-          assertTrue(requests[0].entry.toURL() in results);
+          assertTrue(
+              /** @type {!MetadataRequest} */ (requests[0]).entry.toURL() in
+              results);
           // @ts-ignore: error TS7053: Element implicitly has an 'any' type
           // because expression of type 'any' can't be used to index type '{
           // 'filesystem://A': { imageWidth: number; }; 'filesystem://C': {
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table.ts b/ui/file_manager/file_manager/foreground/js/ui/file_table.ts
index 6e998113..ca212a3 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_table.ts
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_table.ts
@@ -246,8 +246,6 @@
 }
 
 /**
- * TODO: Move this to be a method of TableColumn.
- *
  * Customize the column header to decorate with a11y attributes that announces
  * the sorting used when clicked.
  *
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table_unittest.js b/ui/file_manager/file_manager/foreground/js/ui/file_table_unittest.ts
similarity index 97%
rename from ui/file_manager/file_manager/foreground/js/ui/file_table_unittest.js
rename to ui/file_manager/file_manager/foreground/js/ui/file_table_unittest.ts
index 435f721..6891e53e 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_table_unittest.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_table_unittest.ts
@@ -7,11 +7,9 @@
 import {FileTableColumnModel, MIN_WIDTH} from './file_table.js';
 import {TableColumn} from './table/table_column.js';
 
-/** @type {!FileTableColumnModel} */
-let model;
+let model: FileTableColumnModel;
 
-/** @type {!Array<TableColumn>} */
-let columns;
+let columns: TableColumn[];
 
 export function setUp() {
   columns = [
@@ -27,9 +25,8 @@
 
 /**
  * Extracts column widths from the model.
- * @param {!FileTableColumnModel} model
  */
-function getColumnWidths(model) {
+function getColumnWidths(model: FileTableColumnModel) {
   const widths = [];
   for (let i = 0; i < model.size; i++) {
     widths[i] = model.getWidth(i);
diff --git a/ui/file_manager/file_manager/foreground/js/ui/table/table.ts b/ui/file_manager/file_manager/foreground/js/ui/table/table.ts
index c5f0a01..10cdc5b 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/table/table.ts
+++ b/ui/file_manager/file_manager/foreground/js/ui/table/table.ts
@@ -20,6 +20,8 @@
 import {TableHeader} from './table_header.js';
 import {TableList} from './table_list.js';
 
+
+type RenderFunction = (item: any, table: Table) => ListItem;
 /**
  * Creates a new table element.
  */
@@ -137,7 +139,7 @@
    * Returns render function for row.
    * @return Render function.
    */
-  getRenderFunction(): (_: unknown, _t: Table) => ListItem {
+  getRenderFunction(): RenderFunction {
     return this.renderFunction_;
   }
 
@@ -171,7 +173,7 @@
    * Sets render function for row.
    * @param renderFunction Render function.
    */
-  setRenderFunction(renderFunction: (_item: any, _t: Table) => ListItem) {
+  setRenderFunction(renderFunction: RenderFunction) {
     if (renderFunction === this.renderFunction_) {
       return;
     }
diff --git a/ui/file_manager/file_manager/state/ducks/ui_entries.ts b/ui/file_manager/file_manager/state/ducks/ui_entries.ts
index e31e177..bd3d14a 100644
--- a/ui/file_manager/file_manager/state/ducks/ui_entries.ts
+++ b/ui/file_manager/file_manager/state/ducks/ui_entries.ts
@@ -3,8 +3,9 @@
 // found in the LICENSE file.
 
 import {isSameEntry, isVolumeEntry, sortEntries} from '../../common/js/entry_utils.js';
-import {FakeEntryImpl} from '../../common/js/files_app_entry_types.js';
+import {EntryList} from '../../common/js/files_app_entry_types.js';
 import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js';
+import {FakeEntry} from '../../externs/files_app_entry_interfaces.js';
 import {FileKey, State} from '../../externs/ts/state.js';
 import {Slice} from '../../lib/base_store.js';
 import {cacheEntries, getMyFiles} from '../ducks/all_entries.js';
@@ -34,7 +35,7 @@
 export const addUiEntry = slice.addReducer('add', addUiEntryReducer);
 
 export function addUiEntryReducer(currentState: State, payload: {
-  entry: FakeEntryImpl,
+  entry: FakeEntry|EntryList,
 }): State {
   // Cache entries, so the reducers can use any entry from `allEntries`.
   cacheEntries(currentState, [payload.entry]);
@@ -96,7 +97,7 @@
   key: FileKey,
 }): State {
   const {key} = payload;
-  const entry = getEntry(currentState, key) as FakeEntryImpl | null;
+  const entry = getEntry(currentState, key) as FakeEntry | null;
   if (currentState.uiEntries.find(k => k === key)) {
     // Shallow copy.
     currentState.uiEntries = currentState.uiEntries.filter(k => k !== key);
diff --git a/ui/file_manager/file_manager/state/ducks/volumes.ts b/ui/file_manager/file_manager/state/ducks/volumes.ts
index 2b7d83c..743047d 100644
--- a/ui/file_manager/file_manager/state/ducks/volumes.ts
+++ b/ui/file_manager/file_manager/state/ducks/volumes.ts
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {isOneDriveId, isSameEntry, isVolumeEntry, sortEntries} from '../../common/js/entry_utils.js';
+import {isOneDriveId, isSameEntry, sortEntries} from '../../common/js/entry_utils.js';
 import {EntryList, VolumeEntry} from '../../common/js/files_app_entry_types.js';
 import {isGuestOsEnabled, isSinglePartitionFormatEnabled} from '../../common/js/flags.js';
 import {str} from '../../common/js/translations.js';
 import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js';
-import {FakeEntry, FilesAppEntry} from '../../externs/files_app_entry_interfaces.js';
-import {PropStatus, State, Volume, VolumeId} from '../../externs/ts/state.js';
+import {FilesAppEntry} from '../../externs/files_app_entry_interfaces.js';
+import {FileKey, PropStatus, State, Volume, VolumeId} from '../../externs/ts/state.js';
 import type {VolumeInfo} from '../../externs/volume_info.js';
 import {constants} from '../../foreground/js/constants.js';
 import {Slice} from '../../lib/base_store.js';
@@ -198,6 +198,15 @@
     currentState.allEntries[myFilesEntryKey] = myFilesFileData;
   }
 
+  // When we manipulate the children below, we need to update both
+  // `entry.children_` (usually via `appendChildIfNotExisted/removeChildEntry`)
+  // and also `FileData.children`. This is specific for the purpose of Directory
+  // tree rendering, the tree item only fetch its sub directories on the first
+  // render or when it's being expanded, if a volume mount introduces new
+  // children (e.g. Drive volume and its children), the Tree UI doesn't know it
+  // needs to be re-fetch sub directories because no file watcher event is
+  // triggered for certain cases, hence updating the `FileData.children` here.
+
   // Handles MyFiles volume.
   // It nests the Android, Crostini & GuestOSes inside MyFiles.
   if (volume.volumeType === VolumeType.DOWNLOADS) {
@@ -219,6 +228,16 @@
         appendChildIfNotExisted(newVolumeEntry, childEntry);
         myFilesEntryList.removeChildEntry(childEntry);
       }
+      // Also copy the FileData children of the entry list to the real volume
+      // entry.
+      const myFilesEntryListFileData =
+          getFileData(currentState, myFilesEntryListKey)!;
+      const myFilesVolumeEntryFileData =
+          getFileData(currentState, volumeRootKey)!;
+      currentState.allEntries[volumeRootKey] = {
+        ...myFilesVolumeEntryFileData,
+        children: [...myFilesEntryListFileData.children],
+      };
       // Remove MyFiles entry list from the uiEntries.
       currentState.uiEntries = currentState.uiEntries.filter(
           uiEntryKey => uiEntryKey !== myFilesEntryListKey);
@@ -229,17 +248,20 @@
   // It nests the Drive root (aka MyDrive) inside a EntryList for "Google
   // Drive", and also the fake entries for "Offline" and "Shared with me".
   if (volume.volumeType === VolumeType.DRIVE) {
-    let googleDrive: EntryList|null =
+    let driveFakeRoot: EntryList|null =
         getEntry(currentState, driveRootEntryListKey) as EntryList;
-    const entriesToCache: Array<Entry|FilesAppEntry> = [];
-    if (!googleDrive) {
-      googleDrive = new EntryList(
+    if (!driveFakeRoot) {
+      driveFakeRoot = new EntryList(
           str('DRIVE_DIRECTORY_LABEL'),
           VolumeManagerCommon.RootType.DRIVE_FAKE_ROOT);
-      entriesToCache.push(googleDrive);
-      currentState.uiEntries = [...currentState.uiEntries, googleDrive.toURL()];
+      cacheEntries(currentState, [driveFakeRoot]);
+      currentState.uiEntries =
+          [...currentState.uiEntries, driveFakeRoot.toURL()];
     }
-    appendChildIfNotExisted(googleDrive, newVolumeEntry);
+    const driveRootFileDataChildren: FileKey[] = [];
+
+    appendChildIfNotExisted(driveFakeRoot, newVolumeEntry);
+    driveRootFileDataChildren.push(volumeRootKey);
 
     // We want the order to be
     // - My Drive
@@ -253,38 +275,45 @@
     // to be resolved at this moment because ADD_VOLUME action will only be
     // triggered after resolving all roots.
     if (sharedDriveDisplayRoot) {
-      entriesToCache.push(sharedDriveDisplayRoot);
-      appendChildIfNotExisted(googleDrive, sharedDriveDisplayRoot);
+      cacheEntries(currentState, [sharedDriveDisplayRoot]);
+      appendChildIfNotExisted(driveFakeRoot, sharedDriveDisplayRoot);
+      driveRootFileDataChildren.push(sharedDriveDisplayRoot.toURL());
     }
 
     // Add "Computer" grand root into Drive. It's guaranteed to be resolved at
     // this moment because ADD_VOLUME action will only be triggered after
     // resolving all roots.
     if (computersDisplayRoot) {
-      entriesToCache.push(computersDisplayRoot);
-      appendChildIfNotExisted(googleDrive, computersDisplayRoot);
+      cacheEntries(currentState, [computersDisplayRoot]);
+      appendChildIfNotExisted(driveFakeRoot, computersDisplayRoot);
+      driveRootFileDataChildren.push(computersDisplayRoot.toURL());
     }
 
     // Add "Shared with me" into Drive.
     const fakeSharedWithMe =
         fakeEntries[VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME];
     if (fakeSharedWithMe) {
-      entriesToCache.push(fakeSharedWithMe);
+      cacheEntries(currentState, [fakeSharedWithMe]);
       currentState.uiEntries =
           [...currentState.uiEntries, fakeSharedWithMe.toURL()];
-      appendChildIfNotExisted(googleDrive, fakeSharedWithMe);
+      appendChildIfNotExisted(driveFakeRoot, fakeSharedWithMe);
+      driveRootFileDataChildren.push(fakeSharedWithMe.toURL());
     }
 
     // Add "Offline" into Drive.
     const fakeOffline = fakeEntries[VolumeManagerCommon.RootType.DRIVE_OFFLINE];
     if (fakeOffline) {
-      entriesToCache.push(fakeOffline);
+      cacheEntries(currentState, [fakeOffline]);
       currentState.uiEntries = [...currentState.uiEntries, fakeOffline.toURL()];
-      appendChildIfNotExisted(googleDrive, fakeOffline);
+      appendChildIfNotExisted(driveFakeRoot, fakeOffline);
+      driveRootFileDataChildren.push(fakeOffline.toURL());
     }
 
-    cacheEntries(currentState, entriesToCache);
-    volume.prefixKey = googleDrive.toURL();
+    currentState.allEntries[driveRootEntryListKey] = {
+      ...getFileData(currentState, driveRootEntryListKey),
+      children: driveRootFileDataChildren,
+    };
+    volume.prefixKey = driveFakeRoot.toURL();
   }
 
   // Handles Removable volume.
@@ -313,9 +342,8 @@
         cacheEntries(currentState, [parentEntry]);
         currentState.uiEntries =
             [...currentState.uiEntries, parentEntry.toURL()];
-        // Removable devices with group, its parent should always be ejectable.
-        currentState.allEntries[parentKey].isEjectable = true;
       }
+      const partitionChildEntries: Array<Entry|FilesAppEntry> = [];
       // Update the siblings too.
       Object.values<Volume>(currentState.volumes)
           .filter(
@@ -328,6 +356,7 @@
             const fileData = getFileData(currentState, v.rootKey!);
             if (fileData?.entry) {
               appendChildIfNotExisted(parentEntry!, fileData.entry);
+              partitionChildEntries.push(fileData.entry);
               // For sub-partition from a removable volume, its children icon
               // should be UNKNOWN_REMOVABLE, and it shouldn't be ejectable.
               currentState.allEntries[v.rootKey!] = {
@@ -340,6 +369,7 @@
       // At this point the current `newVolumeEntry` is not in `parentEntry`, we
       // need to add that to that group.
       appendChildIfNotExisted(parentEntry, newVolumeEntry);
+      partitionChildEntries.push(newVolumeEntry);
       volume.prefixKey = parentEntry.toURL();
       // For sub-partition from a removable volume, its children icon should be
       // UNKNOWN_REMOVABLE, and it shouldn't be ejectable.
@@ -349,6 +379,13 @@
         icon: constants.ICON_TYPES.UNKNOWN_REMOVABLE,
         isEjectable: false,
       };
+      currentState.allEntries[parentKey] = {
+        ...getFileData(currentState, parentKey),
+        // Removable devices with group, its parent should always be ejectable.
+        isEjectable: true,
+        children: sortEntries(parentEntry, partitionChildEntries)
+                      .map(entry => entry.toURL()),
+      };
     }
   }
 
@@ -391,67 +428,51 @@
     ...currentState.volumes,
   };
 
-  // We also need to check if the removed volume is a child of My files and if
-  // the volume is a grouped removable device.
-  const volumeTypesNestedInMyFiles = getVolumeTypesNestedInMyFiles();
-  const isGroupedRemovable =
-      volumeToRemove.volumeType === VolumeManagerCommon.VolumeType.REMOVABLE &&
-      volumeToRemove.prefixKey;
-  if (volumeTypesNestedInMyFiles.has(volumeToRemove.volumeType)) {
-    const {myFilesEntry} = getMyFiles(currentState);
-    const children = myFilesEntry.getUIChildren();
-    const volumeEntryExistsInMyFiles = !!children.find(
-        childEntry =>
-            isVolumeEntry(childEntry) && isSameEntry(childEntry, volumeEntry));
-    if (volumeEntryExistsInMyFiles) {
-      // Remove it from the MyFiles UI children.
-      myFilesEntry.removeChildEntry(volumeEntry);
+  if (!volumeToRemove.prefixKey) {
+    return {...currentState};
+  }
+  // We also need to remove it from its prefix entry if there is one.
+  const prefixEntryFileData =
+      getFileData(currentState, volumeToRemove.prefixKey);
+  if (prefixEntryFileData) {
+    const prefixEntry = prefixEntryFileData.entry as EntryList | VolumeEntry;
+    // Remove it from the prefix entry's UI children.
+    prefixEntry.removeChildEntry(volumeEntry);
+    // Remove it from the prefix entry's file data.
+    let newChildren = prefixEntryFileData.children.filter(
+        child => child !== volumeEntry.toURL());
+
+    // If the prefix entry is an entry list for removable partitions, and this
+    // is the last child, remove the prefix entry.
+    if (prefixEntry.rootType === VolumeManagerCommon.RootType.REMOVABLE &&
+        newChildren.length === 0) {
+      currentState.uiEntries = currentState.uiEntries.filter(
+          uiEntryKey => uiEntryKey !== volumeToRemove.prefixKey!);
+    }
+    // If the volume entry is under MyFiles, we need to add the placeholder
+    // entry back after the corresponding volume is removed (e.g. Crostini/Play
+    // files).
+    const volumeTypesNestedInMyFiles = getVolumeTypesNestedInMyFiles();
+    const uiEntryKey = currentState.uiEntries.find(entryKey => {
+      const uiEntry = getEntry(currentState, entryKey)!;
+      return uiEntry.name === volumeEntry.name;
+    });
+    if (volumeTypesNestedInMyFiles.has(volumeToRemove.volumeType) &&
+        uiEntryKey) {
       // Re-add the corresponding placeholder ui entry to the UI children.
-      const uiEntryKey = currentState.uiEntries.find(entryKey => {
-        const uiEntry = getEntry(currentState, entryKey)! as FakeEntry;
-        return uiEntry.name === volumeEntry.name;
-      });
-      if (uiEntryKey) {
-        const uiEntry = getEntry(currentState, uiEntryKey)!;
-        myFilesEntry.addEntry(uiEntry);
-      }
-      // Remove it from the MyFiles file data.
-      const fileData = getFileData(currentState, myFilesEntry.toURL());
-      if (fileData) {
-        let newChildren =
-            fileData.children.filter(child => child !== volumeEntry.toURL());
-        // Re-add the corresponding placeholder ui entry to the file data.
-        if (uiEntryKey) {
-          newChildren = newChildren.concat(uiEntryKey);
-          const childEntries =
-              newChildren.map(childKey => getEntry(currentState, childKey)!);
-          newChildren = sortEntries(myFilesEntry, childEntries)
-                            .map(entry => entry.toURL());
-        }
-        currentState.allEntries[myFilesEntry.toURL()] = {
-          ...fileData,
-          children: newChildren,
-        };
-      }
+      const uiEntry = getEntry(currentState, uiEntryKey)!;
+      prefixEntry.addEntry(uiEntry);
+      // Re-add the corresponding placeholder ui entry to the file data.
+      newChildren = newChildren.concat(uiEntryKey);
+      const childEntries =
+          newChildren.map(childKey => getEntry(currentState, childKey)!);
+      newChildren =
+          sortEntries(prefixEntry, childEntries).map(entry => entry.toURL());
     }
-  } else if (isGroupedRemovable) {
-    const fileData = getFileData(currentState, volumeToRemove.prefixKey!);
-    if (fileData) {
-      // Remove it from the parent UI entry's UI children.
-      (fileData.entry as EntryList).removeChildEntry(volumeEntry);
-      // Remove it from the parent UI entry's file data.
-      const newChildren =
-          fileData.children.filter(child => child !== volumeEntry.toURL());
-      currentState.allEntries[volumeToRemove.prefixKey!] = {
-        ...fileData,
-        children: newChildren,
-      };
-      // If this is the last child, remove the parent UI entry.
-      if (newChildren.length === 0) {
-        currentState.uiEntries = currentState.uiEntries.filter(
-            uiEntryKey => uiEntryKey !== volumeToRemove.prefixKey!);
-      }
-    }
+    currentState.allEntries[volumeToRemove.prefixKey] = {
+      ...prefixEntryFileData,
+      children: newChildren,
+    };
   }
 
   return {
diff --git a/ui/file_manager/file_manager/state/ducks/volumes_unittest.ts b/ui/file_manager/file_manager/state/ducks/volumes_unittest.ts
index ef86c97..a2bcce7 100644
--- a/ui/file_manager/file_manager/state/ducks/volumes_unittest.ts
+++ b/ui/file_manager/file_manager/state/ducks/volumes_unittest.ts
@@ -90,7 +90,10 @@
     allEntries: {
       [playFilesEntry.toURL()]: convertEntryToFileData(playFilesEntry),
       [linuxFilesEntry.toURL()]: convertEntryToFileData(linuxFilesEntry),
-      [myFilesVolumeEntry.toURL()]: fileData,
+      [myFilesVolumeEntry.toURL()]: {
+        ...fileData,
+        children: [playFilesEntry.toURL(), linuxFilesEntry.toURL()],
+      },
     },
     volumes: {
       [linuxFilesVolumeInfo.volumeId]: {
@@ -219,7 +222,22 @@
       // My Files entry list.
       [myFilesFileData.entry.toURL()]: myFilesFileData,
       // Fake Drive root entry list.
-      [driveRootEntryListKey]: convertEntryToFileData(driveFakeRootEntryList),
+      [driveRootEntryListKey]: {
+        ...convertEntryToFileData(driveFakeRootEntryList),
+        children: [
+          driveVolumeEntry.toURL(),
+          sharedDriveDisplayRoot.toURL(),
+          computersDisplayRoot.toURL(),
+          fakeSharedWithMeEntry.toURL(),
+          fakeOfflineEntry.toURL(),
+        ],
+      },
+      // Computers.
+      [computersDisplayRoot.toURL()]:
+          convertEntryToFileData(computersDisplayRoot),
+      // Team drives.
+      [sharedDriveDisplayRoot.toURL()]:
+          convertEntryToFileData(sharedDriveDisplayRoot),
       // Shared with me.
       [fakeSharedWithMeEntry.toURL()]:
           convertEntryToFileData(fakeSharedWithMeEntry),
@@ -299,6 +317,7 @@
         [parentEntry.toURL()]: {
           ...convertEntryToFileData(parentEntry),
           isEjectable: true,
+          children: [volumeEntry.toURL()],
         },
       } :
                              {}),
@@ -394,6 +413,8 @@
       [parentEntry.toURL()]: {
         ...convertEntryToFileData(parentEntry),
         isEjectable: true,
+        children:
+            [partition1VolumeEntry.toURL(), partition2VolumeEntry.toURL()],
       },
     },
     volumes: {
@@ -587,6 +608,7 @@
   const crostiniVolumeEntry = new VolumeEntry(crostiniVolumeInfo);
   const crostiniFileData = convertEntryToFileData(crostiniVolumeEntry);
   initialState.allEntries[crostiniVolumeEntry.toURL()] = crostiniFileData;
+  crostiniVolume.prefixKey = myFilesVolumeEntry.toURL();
   initialState.volumes[crostiniVolume.volumeId] = crostiniVolume;
   fileData.children.push(crostiniVolumeEntry.toURL());
   myFilesVolumeEntry.addEntry(crostiniVolumeEntry);
diff --git a/ui/file_manager/file_names.gni b/ui/file_manager/file_names.gni
index 000dc14..f31b6c1 100644
--- a/ui/file_manager/file_names.gni
+++ b/ui/file_manager/file_names.gni
@@ -23,7 +23,6 @@
   "file_manager/background/js/runtime_loaded_test_util.js",
   "file_manager/background/js/test_util.js",
   "file_manager/background/js/test_util_base.js",
-  "file_manager/background/js/volume_manager_util.js",
 
   # Files Common:
   "file_manager/common/js/array_data_model.js",
@@ -116,7 +115,6 @@
   "file_manager/foreground/js/toolbar_controller.js",
 
   # Metadata:
-  "file_manager/foreground/js/metadata/content_metadata_provider.js",
   "file_manager/foreground/js/metadata/dlp_metadata_provider.js",
   "file_manager/foreground/js/metadata/exif_parser.js",
   "file_manager/foreground/js/metadata/external_metadata_provider.js",
@@ -175,10 +173,9 @@
 # END: static_js_files.
 
 ts_files = [
-  "file_manager/foreground/elements/files_spinner.ts",
-  "file_manager/foreground/elements/xf_button.ts",
-  "file_manager/foreground/elements/xf_circular_progress.ts",
-
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Common.
   "file_manager/common/js/api.ts",
   "file_manager/common/js/app_util.ts",
@@ -200,16 +197,25 @@
   "file_manager/common/js/tslib_shim.ts",
   "file_manager/common/js/util.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Lib.
   "file_manager/lib/actions_producer.ts",
   "file_manager/lib/base_store.ts",
   "file_manager/lib/concurrency_models.ts",
   "file_manager/lib/selector.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # State.
   "file_manager/state/file_key.ts",
   "file_manager/state/store.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Ducks.
   "file_manager/state/ducks/all_entries.ts",
   "file_manager/state/ducks/android_apps.ts",
@@ -224,6 +230,9 @@
   "file_manager/state/ducks/ui_entries.ts",
   "file_manager/state/ducks/volumes.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Containers.
   "file_manager/containers/breadcrumb_container.ts",
   "file_manager/containers/cloud_panel_container.ts",
@@ -231,6 +240,9 @@
   "file_manager/containers/search_container.ts",
   "file_manager/containers/directory_tree_container.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Widgets.
   "file_manager/widgets/xf_base.ts",
   "file_manager/widgets/xf_breadcrumb.ts",
@@ -250,6 +262,9 @@
   "file_manager/widgets/xf_tree_item.ts",
   "file_manager/widgets/xf_password_dialog.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Foreground UI.
   "file_manager/foreground/js/ui/file_grid.ts",
   "file_manager/foreground/js/ui/file_table.ts",
@@ -266,6 +281,9 @@
   "file_manager/foreground/js/ui/table/table.ts",
   "file_manager/foreground/js/ui/table/table_splitter.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Banners.
   "file_manager/foreground/js/ui/banners/drive_bulk_pinning_banner.ts",
   "file_manager/foreground/js/ui/banners/drive_low_individual_space_banner.ts",
@@ -288,6 +306,9 @@
   "file_manager/foreground/js/ui/banners/dlp_restricted_banner.ts",
   "file_manager/foreground/js/ui/banners/types.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Background.
   "file_manager/background/js/app_window_wrapper.ts",
   "file_manager/background/js/crostini.ts",
@@ -303,6 +324,9 @@
   "file_manager/background/js/volume_manager_factory.ts",
   "file_manager/background/js/volume_manager_impl.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Foreground.
   "file_manager/foreground/js/file_transfer_controller.ts",
   "file_manager/foreground/js/banner_controller.ts",
@@ -316,14 +340,32 @@
   "file_manager/foreground/js/task_controller.ts",
   "file_manager/foreground/js/uma_enums.gen.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
+  # Elements.
+  "file_manager/foreground/elements/files_spinner.ts",
+  "file_manager/foreground/elements/xf_button.ts",
+  "file_manager/foreground/elements/xf_circular_progress.ts",
+
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Util.
   "file_manager/widgets/xf_tree_util.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Definitions.
   "file_manager/definitions/file_manager_private.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Metadata:
   "file_manager/foreground/js/metadata/byte_reader.ts",
+  "file_manager/foreground/js/metadata/content_metadata_provider.ts",
   "file_manager/foreground/js/metadata/exif_constants.ts",
   "file_manager/foreground/js/metadata/file_system_metadata_provider.ts",
   "file_manager/foreground/js/metadata/metadata_item.ts",
@@ -376,6 +418,9 @@
 ]
 
 ts_test_files = [
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Common.
   "file_manager/common/js/entry_utils_unittest.ts",
   "file_manager/common/js/file_types_base_unittest.ts",
@@ -384,6 +429,9 @@
   "file_manager/common/js/volume_manager_types_unittest.ts",
   "file_manager/common/js/util_unittest.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Containers
   "file_manager/containers/breadcrumb_container_unittest.ts",
   "file_manager/containers/cloud_panel_container_unittest.ts",
@@ -391,15 +439,24 @@
   "file_manager/containers/nudge_container_unittest.ts",
   "file_manager/containers/search_container_unittest.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Lib:
   "file_manager/lib/actions_producer_unittest.ts",
   "file_manager/lib/base_store_unittest.ts",
   "file_manager/lib/for_tests.ts",
   "file_manager/lib/selector_unittest.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Reducers:
   "file_manager/state/for_tests.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Ducks:
   "file_manager/state/ducks/all_entries_unittest.ts",
   "file_manager/state/ducks/android_apps_unittest.ts",
@@ -414,6 +471,9 @@
   "file_manager/state/ducks/ui_entries_unittest.ts",
   "file_manager/state/ducks/volumes_unittest.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Widgets:
   "file_manager/widgets/xf_breadcrumb_unittest.ts",
   "file_manager/widgets/xf_bulk_pinning_dialog_unittest.ts",
@@ -429,10 +489,17 @@
   "file_manager/widgets/xf_tree_unittest.ts",
   "file_manager/widgets/xf_tree_item_unittest.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Background:
   "file_manager/background/js/crostini_unittest.ts",
   "file_manager/background/js/drive_sync_handler_unittest.ts",
+  "file_manager/background/js/volume_manager_unittest.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Foreground:
   "file_manager/foreground/elements/files_tooltip_unittest.ts",
   "file_manager/foreground/elements/files_toast_unittest.ts",
@@ -444,9 +511,13 @@
   "file_manager/foreground/js/task_controller_unittest.ts",
   "file_manager/foreground/js/metadata/dlp_metadata_provider_unittest.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # UI:
   "file_manager/foreground/js/ui/file_grid_unittest.ts",
   "file_manager/foreground/js/ui/file_table_list_unittest.ts",
+  "file_manager/foreground/js/ui/file_table_unittest.ts",
   "file_manager/foreground/js/ui/grid_unittest.ts",
   "file_manager/foreground/js/ui/list_unittest.ts",
   "file_manager/foreground/js/ui/banners/drive_bulk_pinning_banner_unittest.ts",
@@ -456,7 +527,11 @@
   "file_manager/foreground/js/ui/banners/dlp_restricted_banner_unittest.ts",
   "file_manager/foreground/js/ui/splitter_unittest.ts",
 
+  # 3-line header to avoid conflict.
+  # Don't remove this.
+  # These lines will be removed at the end of the TS migration.
   # Metadata:
+  "file_manager/foreground/js/metadata/content_metadata_provider_unittest.ts",
   "file_manager/foreground/js/metadata/file_system_metadata_provider_unittest.ts",
 ]
 
@@ -497,6 +572,14 @@
   "file_manager/foreground/js/ui/tree.d.ts",
 ]
 
+other_dts_files = [
+  "//tools/typescript/definitions/chrome_event.d.ts",
+  "//tools/typescript/definitions/chrome_test.d.ts",
+  "//tools/typescript/definitions/metrics_private.d.ts",
+  "//tools/typescript/definitions/runtime.d.ts",
+  "//tools/typescript/definitions/tabs.d.ts",
+]
+
 generated_js_files = [
   # Common:
   "file_manager/common/js/file_types_data.js",
@@ -525,7 +608,6 @@
   "file_manager/background/js/file_operation_manager_unittest.js",
   "file_manager/background/js/mock_file_operation_manager.js",
   "file_manager/background/js/mock_volume_manager.js",
-  "file_manager/background/js/volume_manager_unittest.js",
 
   # Foreground:
   "file_manager/foreground/elements/files_xf_elements_unittest.js",
@@ -533,7 +615,6 @@
   "file_manager/foreground/js/metadata/exif_parser_unittest.js",
   "file_manager/foreground/js/metadata/thumbnail_model_unittest.js",
   "file_manager/foreground/js/metadata/metadata_model_unittest.js",
-  "file_manager/foreground/js/metadata/content_metadata_provider_unittest.js",
   "file_manager/foreground/js/metadata/external_metadata_provider_unittest.js",
   "file_manager/foreground/js/metadata/metadata_cache_set_unittest.js",
   "file_manager/foreground/js/metadata/multi_metadata_provider_unittest.js",
@@ -551,7 +632,6 @@
   "file_manager/foreground/js/ui/actions_submenu_unittest.js",
   "file_manager/foreground/js/ui/command_unittest.js",
   "file_manager/foreground/js/ui/context_menu_handler_unittest.js",
-  "file_manager/foreground/js/ui/file_table_unittest.js",
   "file_manager/foreground/js/ui/file_tap_handler_unittest.js",
   "file_manager/foreground/js/ui/install_linux_package_dialog_unittest.js",
   "file_manager/foreground/js/ui/list_selection_model_test_util.js",
diff --git a/ui/file_manager/integration_tests/file_manager/file_dialog.js b/ui/file_manager/integration_tests/file_manager/file_dialog.js
index c4db18246..fbde8a02 100644
--- a/ui/file_manager/integration_tests/file_manager/file_dialog.js
+++ b/ui/file_manager/integration_tests/file_manager/file_dialog.js
@@ -1029,6 +1029,11 @@
   const directoryTree = await DirectoryTreePageObject.create(appId, remoteCall);
   await directoryTree.selectPlaceholderItemByType('bruschetta');
 
+  // Wait for the directory scanning to finish to guarantee the FileWatcher call
+  // is finished.
+  await remoteCall.waitForElement(
+      appId, `#list-container[scan-completed="Bluejohn"]`);
+
   // Wait for the actual volume to appear.
   await directoryTree.waitForItemByType('bruschetta');
 };
@@ -1060,6 +1065,11 @@
   const directoryTree = await DirectoryTreePageObject.create(appId, remoteCall);
   await directoryTree.selectPlaceholderItemByType('bruschetta');
 
+  // Wait for the directory scanning to finish to guarantee the FileWatcher call
+  // is finished.
+  await remoteCall.waitForElement(
+      appId, `#list-container[scan-completed="Bluejohn"]`);
+
   // Wait for the actual volume to appear.
   await directoryTree.waitForItemByType('bruschetta');
 };
diff --git a/ui/file_manager/integration_tests/file_manager/file_display.js b/ui/file_manager/integration_tests/file_manager/file_display.js
index 36ba457c4..69577c2a 100644
--- a/ui/file_manager/integration_tests/file_manager/file_display.js
+++ b/ui/file_manager/integration_tests/file_manager/file_display.js
@@ -573,7 +573,7 @@
 
   // Navigate to the Drive FakeItem.
   const directoryTree = await DirectoryTreePageObject.create(appId, remoteCall);
-  await directoryTree.waitForGroupRootItemByType('drive');
+  await directoryTree.selectGroupRootItemByType('drive');
 
   // The fake Google Drive should be empty.
   await remoteCall.waitForFiles(appId, []);
diff --git a/ui/gfx/mojom/native_handle_types.mojom b/ui/gfx/mojom/native_handle_types.mojom
index 45ce01b..005533e 100644
--- a/ui/gfx/mojom/native_handle_types.mojom
+++ b/ui/gfx/mojom/native_handle_types.mojom
@@ -52,6 +52,15 @@
 };
 
 // gfx::DXGIHandleToken
+// A unique identifier to identify one of the below resources
+// (cannot identify the other at the same time):
+// - Texture corresponding to the GMB handle. Handles get duplicated and OS
+//   provides no other identifier. DXGISharedHandleManager in the GPU services
+//   uses this as a key to cache state across calls that reference the same
+//   texture via different handles.
+// - Fence corresponding to the GPUFenceHandle. Fence handle get duplicated
+//   and OS provides no other identifier. D3DImageBacking in the GPU services
+//   uses this as a key to reference the same fence via different handles.
 [EnableIf=is_win]
 struct DXGIHandleToken {
   mojo_base.mojom.UnguessableToken value;
diff --git a/ui/views/action_view_controller_unittest.cc b/ui/views/action_view_controller_unittest.cc
index b42dc1d..c1e2d53 100644
--- a/ui/views/action_view_controller_unittest.cc
+++ b/ui/views/action_view_controller_unittest.cc
@@ -124,7 +124,13 @@
 }
 
 // Test that action triggered callbacks get called.
-TEST_F(ActionViewControllerTest, TriggerAction) {
+// TODO(crbug.com/1500125): Re-enable this test
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
+#define MAYBE_TriggerAction DISABLED_TriggerAction
+#else
+#define MAYBE_TriggerAction TriggerAction
+#endif
+TEST_F(ActionViewControllerTest, MAYBE_TriggerAction) {
   std::unique_ptr<actions::ActionItem> action_item = CreateEnabledActionItem();
   auto action_view = std::make_unique<MdTextButton>();
   auto action_view_controller =
diff --git a/ui/views/layout/table_layout.cc b/ui/views/layout/table_layout.cc
index ac1b086..e6c01f6 100644
--- a/ui/views/layout/table_layout.cc
+++ b/ui/views/layout/table_layout.cc
@@ -11,6 +11,7 @@
 #include <utility>
 
 #include "base/check_op.h"
+#include "base/containers/span.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/raw_ptr_exclusion.h"
 #include "base/notreached.h"
@@ -579,40 +580,26 @@
 }
 
 void TableLayout::DistributeRemainingHeight(ViewState& view_state) const {
-  int height = view_state.remaining_height;
-  if (height <= 0)
+  if (view_state.remaining_height <= 0) {
     return;
+  }
 
   // Determine the number of resizable rows the view touches.
-  size_t start_row = view_state.start_row;
-  size_t max_row = view_state.start_row + view_state.row_span;
-  const ptrdiff_t resizable_rows =
-      std::count_if(rows_.cbegin() + static_cast<ptrdiff_t>(start_row),
-                    rows_.cbegin() + static_cast<ptrdiff_t>(max_row),
-                    [](const auto& row) { return row.resizable(); });
-
-  const auto adjust_row = [&height](Row& row, int delta) {
-    height -= delta;
-    // If there is slop, we're on the last row; give it all the slop.
-    if (height < delta)
-      delta += height;
-    row.set_size(row.size() + delta);
-  };
-
-  if (resizable_rows > 0) {
-    // There are resizable rows, give the remaining height to them.
-    int row_delta = height / static_cast<int>(resizable_rows);
-    for (size_t i = start_row; i < max_row; ++i) {
-      if (rows_[i].resizable())
-        adjust_row(rows_[i], row_delta);
+  const base::span<Row> rows_to_resize = base::make_span(
+      rows_.begin() + static_cast<ptrdiff_t>(view_state.start_row),
+      view_state.row_span);
+  const auto resizable_rows = static_cast<size_t>(
+      base::ranges::count_if(rows_to_resize, &Row::resizable));
+  size_t remaining_rows =
+      resizable_rows ? resizable_rows : rows_to_resize.size();
+  for (Row& row : rows_to_resize) {
+    if (!resizable_rows || row.resizable()) {
+      const int delta = base::ClampRound(
+          static_cast<float>(view_state.remaining_height) / remaining_rows);
+      row.set_size(row.size() + delta);
+      view_state.remaining_height -= delta;
+      --remaining_rows;
     }
-  } else {
-    // None of the rows are resizable, divvy the remaining height up equally
-    // among all rows the view touches.
-    int row_delta = height / static_cast<int>(view_state.row_span);
-    for (size_t i = start_row; i < max_row; ++i)
-      adjust_row(rows_[i], row_delta);
-    view_state.remaining_height = 0;
   }
 }
 
diff --git a/ui/views/layout/table_layout_unittest.cc b/ui/views/layout/table_layout_unittest.cc
index 00d0b6bc..c2210ecf 100644
--- a/ui/views/layout/table_layout_unittest.cc
+++ b/ui/views/layout/table_layout_unittest.cc
@@ -822,4 +822,32 @@
   ExpectViewBoundsEquals(0, 20, 10, 20, v3);
 }
 
+TEST_F(TableLayoutTest, DistributeRemainingHeight) {
+  layout()
+      .AddColumn(LayoutAlignment::kStart, LayoutAlignment::kStart,
+                 TableLayout::kFixedSize,
+                 TableLayout::ColumnSize::kUsePreferred, 0, 0)
+      .AddColumn(LayoutAlignment::kStart, LayoutAlignment::kStart,
+                 TableLayout::kFixedSize,
+                 TableLayout::ColumnSize::kUsePreferred, 0, 0)
+      .AddRows(2, 1.0f);
+  auto* v1 = host()->AddChildView(CreateSizedView(gfx::Size(10, 40)));
+  v1->SetProperty(views::kTableColAndRowSpanKey, gfx::Size(1, 2));
+  auto* v2 = host()->AddChildView(CreateSizedView(gfx::Size(10, 18)));
+  auto* v3 = host()->AddChildView(CreateSizedView(gfx::Size(10, 19)));
+
+  // The 3 extra height from v1 (compared to v2 + v3) should be fully
+  // distributed between v2 and v3, so the total height is not less than 40.
+  constexpr gfx::Size kDesiredSize(20, 40);
+  EXPECT_EQ(kDesiredSize, GetPreferredSize());
+
+  host()->SetBoundsRect(gfx::Rect(kDesiredSize));
+  layout().Layout(host());
+  ExpectViewBoundsEquals(0, 0, 10, 40, v1);
+  ExpectViewBoundsEquals(10, 0, 10, 18, v2);
+  // Because 3 extra height doesn't divide evenly, it gets rounded, so v2 gets
+  // an extra dip compared to v3; thus v3 should start at y = 18 + 2 = 20.
+  ExpectViewBoundsEquals(10, 20, 10, 19, v3);
+}
+
 }  // namespace views
diff --git a/ui/webui/resources/cr_elements/cr_toggle/cr_toggle.html b/ui/webui/resources/cr_elements/cr_toggle/cr_toggle.html
index 0329ac8d..59e7552 100644
--- a/ui/webui/resources/cr_elements/cr_toggle/cr_toggle.html
+++ b/ui/webui/resources/cr_elements/cr_toggle/cr_toggle.html
@@ -31,13 +31,18 @@
         --cr-toggle-unchecked-button-color:
             var(--color-toggle-button-thumb-off,
                 var(--cr-fallback-color-outline));
+        --cr-toggle-disabled-opacity: 1;
 
         --cr-toggle-checked-ripple-color: var(--cr-active-background-color);
         --cr-toggle-unchecked-ripple-color: var(--cr-active-background-color);
 
         --cr-toggle-ripple-diameter: 20px;
 
-        --cr-toggle-bar-width_: 26px;
+        --cr-toggle-bar-border-color: var(--cr-toggle-unchecked-button-color);
+        --cr-toggle-bar-border: 1px solid var(--cr-toggle-bar-border-color);
+        --cr-toggle-bar-width: 26px;
+
+        --cr-toggle-knob-diameter: 8px;
 
         height: fit-content;
         isolation: isolate;
@@ -81,6 +86,19 @@
             rgba(var(--google-grey-300-rgb), .4);
       }
 
+      :host-context([chrome-refresh-2023]):host(:active) {
+        --cr-toggle-knob-diameter: 10px;
+      }
+
+      :host-context([chrome-refresh-2023]):host([checked]) {
+        --cr-toggle-bar-border-color: var(--cr-toggle-checked-bar-color);
+        --cr-toggle-knob-diameter: 12px;
+      }
+
+      :host-context([chrome-refresh-2023]):host([checked]:active) {
+        --cr-toggle-knob-diameter: 14px;
+      }
+
       :host([disabled]) {
         cursor: initial;
         opacity: var(--cr-disabled-opacity);
@@ -97,7 +115,12 @@
         --cr-toggle-unchecked-button-color:
             var(--color-toggle-button-thumb-off-disabled,
                 var(--cr-fallback-color-disabled-foreground));
-        opacity: 1;
+        --cr-toggle-bar-border-color: var(--cr-toggle-unchecked-button-color);
+        opacity: var(--cr-toggle-disabled-opacity);
+      }
+
+      :host-context([chrome-refresh-2023]):host([checked][disabled]) {
+        --cr-toggle-bar-border: none;
       }
 
       #bar {
@@ -118,27 +141,16 @@
       }
 
       :host-context([chrome-refresh-2023]) #bar {
-        border: 1px solid var(--cr-toggle-unchecked-button-color);
+        border: var(--cr-toggle-bar-border);
         border-radius: 50px;
         box-sizing: border-box;
         display: block;
         height: 16px;
         opacity: 1;
         position: initial;
-        width: var(--cr-toggle-bar-width_);
+        width: var(--cr-toggle-bar-width);
       }
 
-      :host-context([chrome-refresh-2023]):host([checked]) #bar {
-        border-color: var(--cr-toggle-checked-bar-color);
-      }
-
-      :host-context([chrome-refresh-2023]):host([disabled]) #bar {
-        border-color: var(--cr-toggle-unchecked-button-color);
-      }
-
-      :host-context([chrome-refresh-2023]):host([disabled][checked]) #bar {
-        border: none;
-      }
 
       :host-context([chrome-refresh-2023]):host(:focus-visible) #bar {
         outline: 2px solid var(--cr-toggle-checked-bar-color);
@@ -167,8 +179,6 @@
       }
 
       :host-context([chrome-refresh-2023]) #knob {
-        --cr-toggle-knob-diameter_: 8px;
-
         /* Distance between knob center to the edge of the control is the same
            for both checked and unchecked. */
         --cr-toggle-knob-center-edge-distance_: 8px;
@@ -181,14 +191,14 @@
         /* Absolute distance from the center position to either left or
            right. */
         --cr-toggle-knob-travel-distance_: calc(
-            0.5 * var(--cr-toggle-bar-width_) -
+            0.5 * var(--cr-toggle-bar-width) -
             var(--cr-toggle-knob-center-edge-distance_));
 
         /* Positions in the horizontal (x-axis) dimension that the knob can be
           in. The center position is only used for calculations, and is never
           presented to the user. */
         --cr-toggle-knob-position-center_: calc(
-            0.5 * var(--cr-toggle-bar-width_) + -50%);
+            0.5 * var(--cr-toggle-bar-width) + -50%);
         --cr-toggle-knob-position-start_: calc(
             var(--cr-toggle-knob-position-center_) -
             var(--cr-toggle-knob-direction_) *
@@ -199,13 +209,13 @@
             var(--cr-toggle-knob-travel-distance_));
 
         box-shadow: none;
-        height: var(--cr-toggle-knob-diameter_);
+        height: var(--cr-toggle-knob-diameter);
         position: absolute;
         top: 50%;
         transform: translate(var(--cr-toggle-knob-position-start_), -50%);
         transition: transform linear 80ms, background-color linear 80ms,
             width linear 80ms, height linear 80ms;
-        width: var(--cr-toggle-knob-diameter_);
+        width: var(--cr-toggle-knob-diameter);
       }
 
       :host-context([dir=rtl][chrome-refresh-2023]) #knob {
@@ -214,18 +224,11 @@
         --cr-toggle-knob-direction_: -1;
       }
 
-      :host-context([chrome-refresh-2023]):host(:active) #knob {
-        --cr-toggle-knob-diameter_: 10px;
-      }
 
       :host-context([chrome-refresh-2023]):host([checked]) #knob {
-        --cr-toggle-knob-diameter_: 12px;
         transform: translate(var(--cr-toggle-knob-position-end_), -50%);
       }
 
-      :host-context([chrome-refresh-2023]):host([checked]:active) #knob {
-        --cr-toggle-knob-diameter_: 14px;
-      }
 
       :host-context([chrome-refresh-2023]):host([checked]:active) #knob,
       :host-context([chrome-refresh-2023]):host([checked]:hover) #knob {
@@ -239,9 +242,9 @@
         border-radius: 50%;
         content: '';
         height: var(--cr-toggle-ripple-diameter);
-        left: calc(var(--cr-toggle-knob-diameter_) / 2);
+        left: calc(var(--cr-toggle-knob-diameter) / 2);
         position: absolute;
-        top: calc(var(--cr-toggle-knob-diameter_) / 2);
+        top: calc(var(--cr-toggle-knob-diameter) / 2);
         transform: translate(-50%, -50%);
         width: var(--cr-toggle-ripple-diameter);
       }
diff --git a/v8 b/v8
index 9f07854..9565fef 160000
--- a/v8
+++ b/v8
@@ -1 +1 @@
-Subproject commit 9f07854eb0b779fa46b8b64bbc1da4e4a7572878
+Subproject commit 9565fefb3b06c758a9ad4f833f4696f6027fc0ee