diff --git a/DEPS b/DEPS
index f7101d09..050b3c5a 100644
--- a/DEPS
+++ b/DEPS
@@ -297,23 +297,23 @@
   # 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': '2db645fcdde2580151a67f9041fa21e3043af3fc',
+  'skia_revision': '41cb8f2f9d128a67e2782dfb89732477a223cff9',
   # 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': '6c0f2229a1757690518e013c2a3f9f65b80fadb9',
+  'v8_revision': '93defd9910e47e23cc4fdcac88d3169afd7fa147',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '3d0faa02e2376461efe9332d765f65e510bda511',
+  'angle_revision': '6c9530690cd672ea0c07dd0fc7ac1d715481804b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': '16826bfa6f73e938d9f4e01c94af1f8d71028efc',
+  'swiftshader_revision': '708ca9579181a8096193f68ad6c412a5fd302d5b',
   # 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': '744e9f8b0f89481c4623b712f8ecdb02799ddcb5',
+  'pdfium_revision': 'dd844b8101039672374c8bd8e7a6d1d196e0540c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
@@ -368,7 +368,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '47666e0907499ed5c44f6cb15e51ac5096e6f2ba',
+  'catapult_revision': '268569634e0497164b911738502a4438bf1e669b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -376,7 +376,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': 'f32b81c7d1dd1fe3500cac427ad3f1bea4a7c71e',
+  'devtools_frontend_revision': 'f62cac79e0c23253eeb328cb5c1322b026b9eac5',
   # 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.
@@ -412,7 +412,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': '7058a17bda91e64f3c46b8330466776ee585af91',
+  'dawn_revision': '0d3a7bbd7ed9b46cba1c4dc16edf8f2796867592',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -440,7 +440,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling nearby
   # and whatever else without interference from each other.
-  'nearby_revision': 'c48e27d754b4a72508519838d72a7d143accc0f6',
+  'nearby_revision': '30a82350cdda38c01fd6794d9addee89ced7d10f',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling securemessage
   # and whatever else without interference from each other.
@@ -1465,7 +1465,7 @@
     Var('chromium_git') + '/webm/libwebp.git' + '@' +  '7366f7f394af26de814296152c50e673ed0a832f',
 
   'src/third_party/libyuv':
-    Var('chromium_git') + '/libyuv/libyuv.git' + '@' + 'd53f1beecdd8d959f7a3f2e19bd0bd7e7227a233',
+    Var('chromium_git') + '/libyuv/libyuv.git' + '@' + '9b17af9bef41aec80373a7d4689bb77bac33eab5',
 
   'src/third_party/lighttpd': {
       'url': Var('chromium_git') + '/chromium/deps/lighttpd.git' + '@' + Var('lighttpd_revision'),
@@ -1556,7 +1556,7 @@
     Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'fac04ceb3e966f613ed17e98178e9d690280bba6',
 
   'src/third_party/openscreen/src':
-    Var('chromium_git') + '/openscreen' + '@' + '4f5574bdd3efa1641a5aab8ef55972cf14e87b56',
+    Var('chromium_git') + '/openscreen' + '@' + '7f795b08c7e41abdecab742d1577cf22c40dadd7',
 
   'src/third_party/openxr/src': {
     'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + 'bf21ccb1007bb531b45d9978919a56ea5059c245',
@@ -1693,7 +1693,7 @@
       'dep_type': 'cipd',
   },
 
-  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@8eaea8e4521ac774f4504caa5beea485ee012812',
+  'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@d53c356ad7d9a77f43cff070b7af4212fb3f739f',
 
   'src/third_party/vulkan_memory_allocator':
     Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'ebe84bec02c041d28f902da0214bf442743fc907',
@@ -1706,7 +1706,7 @@
 
   # Wayland protocols that add functionality not available in the core protocol.
   'src/third_party/wayland-protocols/src': {
-      'url': Var('chromium_git') + '/external/anongit.freedesktop.org/git/wayland/wayland-protocols.git' + '@' + 'd324986823519c15b2162fc3e0a720f349e43b0c',
+      'url': Var('chromium_git') + '/external/anongit.freedesktop.org/git/wayland/wayland-protocols.git' + '@' + '83866f19d3d61b28e94d71781646466b3a6623d8',
       'condition': 'checkout_linux',
   },
 
@@ -1732,7 +1732,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '2fe73f07ac85b224b717d653a8f0070e8c692dab',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '9d8fdc7bf7d4986c504da3108f493edeeb002155',
+    Var('webrtc_git') + '/src.git' + '@' + '1e688612ccd86cfe42d129118d90ae567502bdd3',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1805,7 +1805,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@f5a06c21c857a894d84c869297670928327a2749',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@3b5fafb36f7c5a624ea9595487720cc05e5edf97',
     'condition': 'checkout_src_internal',
   },
 
@@ -1857,7 +1857,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/projector_app/app',
-        'version': 'dnR2_6Z6RPOQLiUwewqvCYlFK4UJEaeYvUcoviVYiTwC',
+        'version': 'wuGcjqLXk6S1i0PqIGy8RtHPUYSxovyhjjBONlG8XCkC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 6c4cbfaf..d6d170d 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -1207,6 +1207,7 @@
     'testing/merge_scripts/code_coverage/merge_steps.pydeps',
     'third_party/android_platform/development/scripts/stack.pydeps',
     'third_party/blink/renderer/bindings/scripts/build_web_idl_database.pydeps',
+    'third_party/blink/renderer/bindings/scripts/check_generated_file_list.pydeps',
     'third_party/blink/renderer/bindings/scripts/collect_idl_files.pydeps',
     'third_party/blink/renderer/bindings/scripts/generate_bindings.pydeps',
     'third_party/blink/renderer/bindings/scripts/validate_web_idl.pydeps',
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/CookieManagerAdapter.java b/android_webview/glue/java/src/com/android/webview/chromium/CookieManagerAdapter.java
index 75c6be6..76a2cd9 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/CookieManagerAdapter.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/CookieManagerAdapter.java
@@ -29,6 +29,10 @@
         mChromeCookieManager = chromeCookieManager;
     }
 
+    public AwCookieManager getCookieManager() {
+        return mChromeCookieManager;
+    }
+
     @Override
     public synchronized void setAcceptCookie(boolean accept) {
         mChromeCookieManager.setAcceptCookie(accept);
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebkitToSharedGlueConverter.java b/android_webview/glue/java/src/com/android/webview/chromium/WebkitToSharedGlueConverter.java
index 603c2eb..3fe8d005 100644
--- a/android_webview/glue/java/src/com/android/webview/chromium/WebkitToSharedGlueConverter.java
+++ b/android_webview/glue/java/src/com/android/webview/chromium/WebkitToSharedGlueConverter.java
@@ -5,6 +5,7 @@
 package com.android.webview.chromium;
 
 import android.os.Build;
+import android.webkit.CookieManager;
 import android.webkit.SafeBrowsingResponse;
 import android.webkit.ServiceWorkerWebSettings;
 import android.webkit.WebMessagePort;
@@ -17,6 +18,7 @@
 
 import org.chromium.android_webview.AwContentsClient.AwWebResourceError;
 import org.chromium.android_webview.AwContentsClient.AwWebResourceRequest;
+import org.chromium.android_webview.AwCookieManager;
 import org.chromium.android_webview.AwServiceWorkerSettings;
 import org.chromium.android_webview.AwSettings;
 import org.chromium.android_webview.safe_browsing.AwSafeBrowsingResponse;
@@ -29,6 +31,10 @@
  * This class is used to minimize dependencies from the support-library-glue on the webkit-glue.
  */
 public class WebkitToSharedGlueConverter {
+    public static AwCookieManager getCookieManager(CookieManager cookieManager) {
+        return ((CookieManagerAdapter) cookieManager).getCookieManager();
+    }
+
     public static SharedWebViewChromium getSharedWebViewChromium(WebView webview) {
         WebViewChromium webviewChromium = (WebViewChromium) webview.getWebViewProvider();
         return webviewChromium.getSharedWebViewChromium();
diff --git a/android_webview/support_library/BUILD.gn b/android_webview/support_library/BUILD.gn
index 8377b2e..eacd9a0 100644
--- a/android_webview/support_library/BUILD.gn
+++ b/android_webview/support_library/BUILD.gn
@@ -25,6 +25,7 @@
     "java/src/org/chromium/support_lib_glue/SupportLibWebSettingsAdapter.java",
     "java/src/org/chromium/support_lib_glue/SupportLibWebViewChromium.java",
     "java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java",
+    "java/src/org/chromium/support_lib_glue/SupportLibWebViewCookieManagerAdapter.java",
     "java/src/org/chromium/support_lib_glue/SupportLibWebViewRendererAdapter.java",
     "java/src/org/chromium/support_lib_glue/SupportLibWebViewRendererClientAdapter.java",
     "java/src/org/chromium/support_lib_glue/SupportLibWebkitToCompatConverterAdapter.java",
diff --git a/android_webview/support_library/boundary_interfaces/BUILD.gn b/android_webview/support_library/boundary_interfaces/BUILD.gn
index c20f885b..6ad2c3c 100644
--- a/android_webview/support_library/boundary_interfaces/BUILD.gn
+++ b/android_webview/support_library/boundary_interfaces/BUILD.gn
@@ -29,6 +29,7 @@
     "src/org/chromium/support_lib_boundary/WebResourceRequestBoundaryInterface.java",
     "src/org/chromium/support_lib_boundary/WebSettingsBoundaryInterface.java",
     "src/org/chromium/support_lib_boundary/WebViewClientBoundaryInterface.java",
+    "src/org/chromium/support_lib_boundary/WebViewCookieManagerBoundaryInterface.java",
     "src/org/chromium/support_lib_boundary/WebViewProviderBoundaryInterface.java",
     "src/org/chromium/support_lib_boundary/WebViewProviderFactoryBoundaryInterface.java",
     "src/org/chromium/support_lib_boundary/WebViewRendererBoundaryInterface.java",
diff --git a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebViewCookieManagerBoundaryInterface.java b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebViewCookieManagerBoundaryInterface.java
new file mode 100644
index 0000000..e29c908c
--- /dev/null
+++ b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebViewCookieManagerBoundaryInterface.java
@@ -0,0 +1,14 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.support_lib_boundary;
+
+import java.util.List;
+
+/**
+ * Boundary interface for CookieManagerCompat.
+ */
+public interface WebViewCookieManagerBoundaryInterface {
+    List<String> getCookieInfo(String url);
+}
diff --git a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebkitToCompatConverterBoundaryInterface.java b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebkitToCompatConverterBoundaryInterface.java
index 1913b868..da335f1 100644
--- a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebkitToCompatConverterBoundaryInterface.java
+++ b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/WebkitToCompatConverterBoundaryInterface.java
@@ -63,4 +63,8 @@
             /* WebMessagePort */ Object webMessagePort);
     /* WebMessagePort */ Object convertWebMessagePort(
             /* SupportLibWebMessagePort */ InvocationHandler webMessagePort);
+
+    // CookieManager
+    /* SupportLibWebViewCookieManager */ InvocationHandler convertCookieManager(
+            Object cookieManager);
 }
diff --git a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java
index 4c38495..e4abaaee 100644
--- a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java
+++ b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java
@@ -210,4 +210,7 @@
     // WebSettingsCompat.getEnterpriseAuthenticationAppLinkPolicyEnabled
     public static final String ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY =
             "ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY";
+
+    // CookieManagerCompat.getCookieInfo
+    public static final String GET_COOKIE_INFO = "GET_COOKIE_INFO";
 }
diff --git a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java
index bf96ec9e..10a0c16 100644
--- a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java
+++ b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewChromiumFactory.java
@@ -88,6 +88,7 @@
                     Features.GET_VARIATIONS_HEADER,
                     Features.ALGORITHMIC_DARKENING,
                     Features.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY,
+                    Features.GET_COOKIE_INFO + Features.DEV_SUFFIX,
                     // Add new features above. New features must include `+ Features.DEV_SUFFIX`
                     // when they're initially added (this can be removed in a future CL). The final
                     // feature should have a trailing comma for cleaner diffs.
@@ -158,6 +159,7 @@
             ApiCall.GET_VARIATIONS_HEADER,
             ApiCall.WEB_SETTINGS_GET_ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY_ENABLED,
             ApiCall.WEB_SETTINGS_SET_ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY_ENABLED,
+            ApiCall.COOKIE_MANAGER_GET_COOKIE_INFO,
             // Add new constants above. The final constant should have a trailing comma for cleaner
             // diffs.
     })
@@ -225,8 +227,9 @@
         int GET_VARIATIONS_HEADER = 60;
         int WEB_SETTINGS_GET_ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY_ENABLED = 61;
         int WEB_SETTINGS_SET_ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY_ENABLED = 62;
+        int COOKIE_MANAGER_GET_COOKIE_INFO = 63;
         // Remember to update AndroidXWebkitApiCall in enums.xml when adding new values here
-        int COUNT = 63;
+        int COUNT = 64;
     }
     // clang-format on
 
diff --git a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewCookieManagerAdapter.java b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewCookieManagerAdapter.java
new file mode 100644
index 0000000..66c3bbe
--- /dev/null
+++ b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebViewCookieManagerAdapter.java
@@ -0,0 +1,25 @@
+package org.chromium.support_lib_glue;
+
+import static org.chromium.support_lib_glue.SupportLibWebViewChromiumFactory.recordApiCall;
+
+import org.chromium.android_webview.AwCookieManager;
+import org.chromium.support_lib_boundary.WebViewCookieManagerBoundaryInterface;
+
+import java.util.List;
+
+/**
+ * Adapter between WebViewCookieManagerBoundaryInterface and AwCookieManager.
+ */
+class SupportLibWebViewCookieManagerAdapter implements WebViewCookieManagerBoundaryInterface {
+    private final AwCookieManager mAwCookieManager;
+
+    public SupportLibWebViewCookieManagerAdapter(AwCookieManager awCookieManager) {
+        mAwCookieManager = awCookieManager;
+    }
+
+    @Override
+    public List<String> getCookieInfo(String url) {
+        recordApiCall(SupportLibWebViewChromiumFactory.ApiCall.COOKIE_MANAGER_GET_COOKIE_INFO);
+        return mAwCookieManager.getCookieInfo(url);
+    }
+}
diff --git a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebkitToCompatConverterAdapter.java b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebkitToCompatConverterAdapter.java
index 06b7cef..e716d94 100644
--- a/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebkitToCompatConverterAdapter.java
+++ b/android_webview/support_library/java/src/org/chromium/support_lib_glue/SupportLibWebkitToCompatConverterAdapter.java
@@ -5,6 +5,7 @@
 package org.chromium.support_lib_glue;
 
 import android.os.Build;
+import android.webkit.CookieManager;
 import android.webkit.SafeBrowsingResponse;
 import android.webkit.ServiceWorkerWebSettings;
 import android.webkit.WebMessagePort;
@@ -125,4 +126,13 @@
                         .getDelegateFromInvocationHandler(webMessagePort);
         return new WebMessagePortAdapter(supportLibMessagePort.getPort());
     }
+
+    // WebViewCookieManagerBoundaryInterface
+    @Override
+    public InvocationHandler convertCookieManager(Object cookieManager) {
+        return BoundaryInterfaceReflectionUtil.createInvocationHandlerFor(
+                new SupportLibWebViewCookieManagerAdapter(
+                        WebkitToSharedGlueConverter.getCookieManager(
+                                (CookieManager) cookieManager)));
+    }
 }
diff --git a/ash/components/audio/audio_devices_pref_handler_impl.cc b/ash/components/audio/audio_devices_pref_handler_impl.cc
index dc9067ce..e6878357 100644
--- a/ash/components/audio/audio_devices_pref_handler_impl.cc
+++ b/ash/components/audio/audio_devices_pref_handler_impl.cc
@@ -73,7 +73,7 @@
 // (which is expected to be equal to |intended_key|), if the entry can
 // be found.
 // Returns whether the migration occurred.
-bool MigrateDeviceIdInSettings(base::Value* settings,
+bool MigrateDeviceIdInSettings(base::Value::Dict* settings,
                                const std::string& intended_key,
                                const AudioDevice& device) {
   if (device.stable_device_id_version == 1)
@@ -82,12 +82,12 @@
   DCHECK_EQ(2, device.stable_device_id_version);
 
   std::string old_device_id = GetVersionedDeviceIdString(device, 1);
-  absl::optional<base::Value> value = settings->ExtractKey(old_device_id);
+  absl::optional<base::Value> value = settings->Extract(old_device_id);
   if (!value)
     return false;
 
   DCHECK_EQ(intended_key, GetDeviceIdString(device));
-  settings->SetPath(intended_key, std::move(*value));
+  settings->SetByDottedPath(intended_key, std::move(*value));
   return true;
 }
 
@@ -122,9 +122,9 @@
   // if one exists.
   if (device.stable_device_id_version == 2) {
     std::string old_device_id = GetVersionedDeviceIdString(device, 1);
-    device_volume_settings_.RemoveKey(old_device_id);
+    device_volume_settings_.Remove(old_device_id);
   }
-  device_volume_settings_.SetDoubleKey(GetDeviceIdString(device), value);
+  device_volume_settings_.Set(GetDeviceIdString(device), value);
 
   SaveDevicesVolumePref();
 }
@@ -139,22 +139,22 @@
   // Use this opportunity to remove input device record from
   // |device_volume_settings_|.
   // TODO(baileyberro): Remove this check in M94.
-  if (device_volume_settings_.FindKey(device_id)) {
-    device_volume_settings_.RemoveKey(device_id);
+  if (device_volume_settings_.Find(device_id)) {
+    device_volume_settings_.Remove(device_id);
     SaveDevicesVolumePref();
   }
 
-  device_gain_settings_.SetDoubleKey(device_id, value);
+  device_gain_settings_.Set(device_id, value);
   SaveDevicesGainPref();
 }
 
 bool AudioDevicesPrefHandlerImpl::GetMuteValue(const AudioDevice& device) {
   std::string device_id_str = GetDeviceIdString(device);
-  if (!device_mute_settings_.FindKey(device_id_str))
+  if (!device_mute_settings_.Find(device_id_str))
     MigrateDeviceMuteSettings(device_id_str, device);
 
   int mute =
-      device_mute_settings_.FindIntKey(device_id_str).value_or(kPrefMuteOff);
+      device_mute_settings_.FindInt(device_id_str).value_or(kPrefMuteOff);
   return (mute == kPrefMuteOn);
 }
 
@@ -164,28 +164,29 @@
   // if one exists.
   if (device.stable_device_id_version == 2) {
     std::string old_device_id = GetVersionedDeviceIdString(device, 1);
-    device_mute_settings_.RemoveKey(old_device_id);
+    device_mute_settings_.Remove(old_device_id);
   }
-  device_mute_settings_.SetIntKey(GetDeviceIdString(device),
-                                  mute ? kPrefMuteOn : kPrefMuteOff);
+  device_mute_settings_.Set(GetDeviceIdString(device),
+                            mute ? kPrefMuteOn : kPrefMuteOff);
   SaveDevicesMutePref();
 }
 
 void AudioDevicesPrefHandlerImpl::SetDeviceActive(const AudioDevice& device,
                                                   bool active,
                                                   bool activate_by_user) {
-  base::Value dict(base::Value::Type::DICTIONARY);
-  dict.SetBoolKey(kActiveKey, active);
+  base::Value::Dict dict;
+  dict.Set(kActiveKey, active);
   if (active)
-    dict.SetBoolKey(kActivateByUserKey, activate_by_user);
+    dict.Set(kActivateByUserKey, activate_by_user);
 
   // Use this opportunity to remove device record under deprecated device ID,
   // if one exists.
   if (device.stable_device_id_version == 2) {
     std::string old_device_id = GetVersionedDeviceIdString(device, 1);
-    device_state_settings_.RemoveKey(old_device_id);
+    device_state_settings_.Remove(old_device_id);
   }
-  device_state_settings_.SetPath(GetDeviceIdString(device), std::move(dict));
+  device_state_settings_.SetByDottedPath(GetDeviceIdString(device),
+                                         std::move(dict));
   SaveDevicesStatePref();
 }
 
@@ -193,18 +194,19 @@
                                                   bool* active,
                                                   bool* activate_by_user) {
   const std::string device_id_str = GetDeviceIdString(device);
-  if (!device_state_settings_.FindKey(device_id_str) &&
+  if (!device_state_settings_.Find(device_id_str) &&
       !MigrateDevicesStatePref(device_id_str, device)) {
     return false;
   }
 
-  base::Value* dict = device_state_settings_.FindDictPath(device_id_str);
+  base::Value::Dict* dict =
+      device_state_settings_.FindDictByDottedPath(device_id_str);
   if (!dict) {
     LOG(ERROR) << "Could not get device state for device:" << device.ToString();
     return false;
   }
 
-  absl::optional<bool> active_opt = dict->FindBoolKey(kActiveKey);
+  absl::optional<bool> active_opt = dict->FindBool(kActiveKey);
   if (!active_opt.has_value()) {
     LOG(ERROR) << "Could not get active value for device:" << device.ToString();
     return false;
@@ -215,7 +217,7 @@
     return true;
 
   absl::optional<bool> activate_by_user_opt =
-      dict->FindBoolKey(kActivateByUserKey);
+      dict->FindBool(kActivateByUserKey);
   if (!activate_by_user_opt.has_value()) {
     LOG(ERROR) << "Could not get activate_by_user value for previously "
                   "active device:"
@@ -245,18 +247,18 @@
     const AudioDevice& device) {
   DCHECK(!device.is_input);
   std::string device_id_str = GetDeviceIdString(device);
-  if (!device_volume_settings_.FindKey(device_id_str))
+  if (!device_volume_settings_.Find(device_id_str))
     MigrateDeviceVolumeGainSettings(device_id_str, device);
-  return *device_volume_settings_.FindDoubleKey(device_id_str);
+  return *device_volume_settings_.FindDouble(device_id_str);
 }
 
 double AudioDevicesPrefHandlerImpl::GetInputGainPrefValue(
     const AudioDevice& device) {
   DCHECK(device.is_input);
   std::string device_id_str = GetDeviceIdString(device);
-  if (!device_gain_settings_.FindKey(device_id_str))
+  if (!device_gain_settings_.Find(device_id_str))
     SetInputGainPrefValue(device, kDefaultInputGainPercent);
-  return *device_gain_settings_.FindDoubleKey(device_id_str);
+  return *device_gain_settings_.FindDouble(device_id_str);
 }
 
 double AudioDevicesPrefHandlerImpl::GetDeviceDefaultOutputVolume(
@@ -279,11 +281,7 @@
 
 AudioDevicesPrefHandlerImpl::AudioDevicesPrefHandlerImpl(
     PrefService* local_state)
-    : device_mute_settings_(base::Value::Type::DICTIONARY),
-      device_volume_settings_(base::Value::Type::DICTIONARY),
-      device_gain_settings_(base::Value::Type::DICTIONARY),
-      device_state_settings_(base::Value::Type::DICTIONARY),
-      local_state_(local_state) {
+    : local_state_(local_state) {
   InitializePrefObservers();
 
   LoadDevicesMutePref();
@@ -303,57 +301,49 @@
 }
 
 void AudioDevicesPrefHandlerImpl::LoadDevicesMutePref() {
-  const base::Value* mute_prefs =
-      local_state_->GetDictionary(prefs::kAudioDevicesMute);
-  if (mute_prefs)
-    device_mute_settings_ = mute_prefs->Clone();
+  const base::Value::Dict& mute_prefs =
+      local_state_->GetValueDict(prefs::kAudioDevicesMute);
+  device_mute_settings_ = mute_prefs.Clone();
 }
 
 void AudioDevicesPrefHandlerImpl::SaveDevicesMutePref() {
   DictionaryPrefUpdate dict_update(local_state_, prefs::kAudioDevicesMute);
-  dict_update->DictClear();
-  dict_update->MergeDictionary(&device_mute_settings_);
+  dict_update->GetDict() = device_mute_settings_.Clone();
 }
 
 void AudioDevicesPrefHandlerImpl::LoadDevicesVolumePref() {
-  const base::Value* volume_prefs =
-      local_state_->GetDictionary(prefs::kAudioDevicesVolumePercent);
-  if (volume_prefs)
-    device_volume_settings_ = volume_prefs->Clone();
+  const base::Value::Dict& volume_prefs =
+      local_state_->GetValueDict(prefs::kAudioDevicesVolumePercent);
+  device_volume_settings_ = volume_prefs.Clone();
 }
 
 void AudioDevicesPrefHandlerImpl::SaveDevicesVolumePref() {
   DictionaryPrefUpdate dict_update(local_state_,
                                    prefs::kAudioDevicesVolumePercent);
-  dict_update->DictClear();
-  dict_update->MergeDictionary(&device_volume_settings_);
+  dict_update->GetDict() = device_volume_settings_.Clone();
 }
 
 void AudioDevicesPrefHandlerImpl::LoadDevicesGainPref() {
-  const base::Value* gain_prefs =
-      local_state_->GetDictionary(prefs::kAudioDevicesGainPercent);
-  if (gain_prefs)
-    device_gain_settings_ = gain_prefs->Clone();
+  const base::Value::Dict& gain_prefs =
+      local_state_->GetValueDict(prefs::kAudioDevicesGainPercent);
+  device_gain_settings_ = gain_prefs.Clone();
 }
 
 void AudioDevicesPrefHandlerImpl::SaveDevicesGainPref() {
   DictionaryPrefUpdate dict_update(local_state_,
                                    prefs::kAudioDevicesGainPercent);
-  dict_update->DictClear();
-  dict_update->MergeDictionary(&device_gain_settings_);
+  dict_update->GetDict() = device_gain_settings_.Clone();
 }
 
 void AudioDevicesPrefHandlerImpl::LoadDevicesStatePref() {
-  const base::Value* state_prefs =
-      local_state_->GetDictionary(prefs::kAudioDevicesState);
-  if (state_prefs)
-    device_state_settings_ = state_prefs->Clone();
+  const base::Value::Dict& state_prefs =
+      local_state_->GetValueDict(prefs::kAudioDevicesState);
+  device_state_settings_ = state_prefs.Clone();
 }
 
 void AudioDevicesPrefHandlerImpl::SaveDevicesStatePref() {
   DictionaryPrefUpdate dict_update(local_state_, prefs::kAudioDevicesState);
-  dict_update->DictClear();
-  dict_update->MergeDictionary(&device_state_settings_);
+  dict_update->GetDict() = device_state_settings_.Clone();
 }
 
 bool AudioDevicesPrefHandlerImpl::MigrateDevicesStatePref(
@@ -374,7 +364,7 @@
     // If there was no recorded value for deprecated device ID, use value from
     // global mute pref.
     int old_mute = local_state_->GetInteger(prefs::kAudioMute);
-    device_mute_settings_.SetIntKey(device_key, old_mute);
+    device_mute_settings_.Set(device_key, old_mute);
   }
   SaveDevicesMutePref();
 }
@@ -388,7 +378,7 @@
     // If there was no recorded value for deprecated device ID, use value from
     // global vloume pref.
     double old_volume = local_state_->GetDouble(prefs::kAudioVolumePercent);
-    device_volume_settings_.SetDoubleKey(device_key, old_volume);
+    device_volume_settings_.Set(device_key, old_volume);
   }
   SaveDevicesVolumePref();
 }
diff --git a/ash/components/audio/audio_devices_pref_handler_impl.h b/ash/components/audio/audio_devices_pref_handler_impl.h
index 8222125..38d92998a 100644
--- a/ash/components/audio/audio_devices_pref_handler_impl.h
+++ b/ash/components/audio/audio_devices_pref_handler_impl.h
@@ -114,10 +114,10 @@
   // Notifies the AudioPrefObserver for audio policy pref changes.
   void NotifyAudioPolicyChange();
 
-  base::Value device_mute_settings_;
-  base::Value device_volume_settings_;
-  base::Value device_gain_settings_;
-  base::Value device_state_settings_;
+  base::Value::Dict device_mute_settings_;
+  base::Value::Dict device_volume_settings_;
+  base::Value::Dict device_gain_settings_;
+  base::Value::Dict device_state_settings_;
 
   PrefService* local_state_;  // not owned
 
diff --git a/ash/webui/common/backend/plural_string_handler_unittest.cc b/ash/webui/common/backend/plural_string_handler_unittest.cc
index a086428..6bf1d10 100644
--- a/ash/webui/common/backend/plural_string_handler_unittest.cc
+++ b/ash/webui/common/backend/plural_string_handler_unittest.cc
@@ -49,11 +49,11 @@
 TEST_F(PluralStringHandlerTest, PluralString) {
   // base::RunLoop run_loop;
   const int call_data_count_before_call = web_ui_.call_data().size();
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kHandlerFunctionName);
   args.Append("editButtonLabel");
   args.Append(/*count=*/2);
-  web_ui_.HandleReceivedMessage("getPluralString", &args);
+  web_ui_.HandleReceivedMessage("getPluralString", args);
   base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(call_data_count_before_call + 1u, web_ui_.call_data().size());
@@ -67,11 +67,11 @@
 
 TEST_F(PluralStringHandlerTest, SingularString) {
   const int call_data_count_before_call = web_ui_.call_data().size();
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kHandlerFunctionName);
   args.Append("editButtonLabel");
   args.Append(/*count=*/1);
-  web_ui_.HandleReceivedMessage("getPluralString", &args);
+  web_ui_.HandleReceivedMessage("getPluralString", args);
   base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(call_data_count_before_call + 1u, web_ui_.call_data().size());
@@ -84,11 +84,11 @@
 }
 
 TEST_F(PluralStringHandlerTest, InvalidPluralStringRequest) {
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kHandlerFunctionName);
   args.Append(/*name=*/"invalidKey");
   args.Append(/*count=*/2);
-  web_ui_.HandleReceivedMessage("getPluralString", &args);
+  web_ui_.HandleReceivedMessage("getPluralString", args);
   base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(0u, web_ui_.call_data().size());
diff --git a/ash/webui/diagnostics_ui/backend/session_log_handler_unittest.cc b/ash/webui/diagnostics_ui/backend/session_log_handler_unittest.cc
index 8abfc01d..2c3991b1 100644
--- a/ash/webui/diagnostics_ui/backend/session_log_handler_unittest.cc
+++ b/ash/webui/diagnostics_ui/backend/session_log_handler_unittest.cc
@@ -202,8 +202,8 @@
     session_log_handler_->SetTaskRunnerForTesting(task_runner_);
 
     // Call handler to enable Javascript.
-    base::ListValue args;
-    web_ui_.HandleReceivedMessage("initialize", &args);
+    base::Value::List args;
+    web_ui_.HandleReceivedMessage("initialize", args);
   }
 
   void TearDown() override {
@@ -264,10 +264,10 @@
   // Select file
   base::FilePath log_path = temp_dir_.GetPath().AppendASCII("test_path");
   ui::SelectFileDialog::SetFactory(new TestSelectFileDialogFactory(log_path));
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kHandlerFunctionName);
   session_log_handler_->SetLogCreatedClosureForTest(run_loop.QuitClosure());
-  web_ui_.HandleReceivedMessage("saveSessionLog", &args);
+  web_ui_.HandleReceivedMessage("saveSessionLog", args);
   run_loop.RunUntilIdle();
   const std::string expected_system_log_header = "=== System ===";
   const std::string expected_system_info_section_name = "--- System Info ---";
@@ -319,10 +319,10 @@
   // Simulate select file
   base::FilePath log_path = temp_dir_.GetPath().AppendASCII("test_path");
   ui::SelectFileDialog::SetFactory(new TestSelectFileDialogFactory(log_path));
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kHandlerFunctionName);
   session_log_handler_->SetLogCreatedClosureForTest(run_loop.QuitClosure());
-  web_ui_.HandleReceivedMessage("saveSessionLog", &args);
+  web_ui_.HandleReceivedMessage("saveSessionLog", args);
   RunTasks();
 
   const std::vector<std::string> log_lines = GetCombinedLogContents(log_path);
@@ -356,11 +356,11 @@
   ui::SelectFileDialog::SetFactory(new TestSelectFileDialogFactory(log_path));
 
   const size_t call_data_count_before_call = web_ui_.call_data().size();
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kHandlerFunctionName);
   base::RunLoop run_loop;
   session_log_handler_->SetLogCreatedClosureForTest(run_loop.QuitClosure());
-  web_ui_.HandleReceivedMessage("saveSessionLog", &args);
+  web_ui_.HandleReceivedMessage("saveSessionLog", args);
   RunTasks();
   run_loop.RunUntilIdle();
 
@@ -379,9 +379,9 @@
       new TestSelectFileDialogFactory(base::FilePath()));
 
   const size_t call_data_count_before_call = web_ui_.call_data().size();
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kHandlerFunctionName);
-  web_ui_.HandleReceivedMessage("saveSessionLog", &args);
+  web_ui_.HandleReceivedMessage("saveSessionLog", args);
   RunTasks();
 
   EXPECT_EQ(call_data_count_before_call + 1u, web_ui_.call_data().size());
@@ -397,13 +397,13 @@
 TEST_F(SessionLogHandlerTest, AddToHoldingSpace) {
   base::FilePath log_path = temp_dir_.GetPath().AppendASCII("test_path");
   ui::SelectFileDialog::SetFactory(new TestSelectFileDialogFactory(log_path));
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kHandlerFunctionName);
 
   EXPECT_CALL(holding_space_client(), AddDiagnosticsLog(testing::Eq(log_path)));
   base::RunLoop run_loop;
   session_log_handler_->SetLogCreatedClosureForTest(run_loop.QuitClosure());
-  web_ui_.HandleReceivedMessage("saveSessionLog", &args);
+  web_ui_.HandleReceivedMessage("saveSessionLog", args);
   RunTasks();
   run_loop.RunUntilIdle();
 }
@@ -413,12 +413,12 @@
 TEST_F(SessionLogHandlerTest, CleanUpDialogOnDeconstruct) {
   base::FilePath log_path = temp_dir_.GetPath().AppendASCII("test_path");
   ui::SelectFileDialog::SetFactory(new TestSelectFileDialogFactory(log_path));
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kHandlerFunctionName);
   base::RunLoop run_loop;
 
   session_log_handler_->SetLogCreatedClosureForTest(run_loop.QuitClosure());
-  web_ui_.HandleReceivedMessage("saveSessionLog", &args);
+  web_ui_.HandleReceivedMessage("saveSessionLog", args);
   EXPECT_NO_FATAL_FAILURE(session_log_handler_.reset());
   EXPECT_NO_FATAL_FAILURE(task_runner_.reset());
   EXPECT_NO_FATAL_FAILURE(run_loop.RunUntilIdle());
@@ -432,14 +432,14 @@
       ash::features::kEnableLogControllerForDiagnosticsApp);
   base::FilePath log_path = temp_dir_.GetPath().AppendASCII("test_path");
   ui::SelectFileDialog::SetFactory(new TestSelectFileDialogFactory(log_path));
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kHandlerFunctionName);
   base::RunLoop run_loop;
 
   session_log_handler_->SetLogCreatedClosureForTest(
       base::BindLambdaForTesting([]() { NOTREACHED(); }));
   EXPECT_EQ(0u, task_runner_->NumPendingTasks());
-  web_ui_.HandleReceivedMessage("saveSessionLog", &args);
+  web_ui_.HandleReceivedMessage("saveSessionLog", args);
   EXPECT_EQ(1u, task_runner_->NumPendingTasks());
   EXPECT_NO_FATAL_FAILURE(session_log_handler_.reset());
   task_runner_->RunUntilIdle();
diff --git a/ash/webui/diagnostics_ui/diagnostics_metrics_message_handler_unittest.cc b/ash/webui/diagnostics_ui/diagnostics_metrics_message_handler_unittest.cc
index 39fdd6d..686e6cc 100644
--- a/ash/webui/diagnostics_ui/diagnostics_metrics_message_handler_unittest.cc
+++ b/ash/webui/diagnostics_ui/diagnostics_metrics_message_handler_unittest.cc
@@ -44,10 +44,10 @@
   }
 
   void SendRecordNavigation(NavigationView from, NavigationView to) {
-    base::ListValue args;
+    base::Value::List args;
     args.Append(base::Value(static_cast<int>(from)));
     args.Append(base::Value(static_cast<int>(to)));
-    web_ui_.HandleReceivedMessage(kRecordNavigation, &args);
+    web_ui_.HandleReceivedMessage(kRecordNavigation, args);
 
     task_environment_.RunUntilIdle();
   }
@@ -185,31 +185,31 @@
 
 TEST_F(DiagnosticsMetricsMessageHandlerTest,
        HandleRecordNavigationWithoutArgs) {
-  base::ListValue args;
+  base::Value::List args;
 
   NavigationView expected_view = NavigationView::kSystem;
   InitializeHandler(expected_view);
 
   EXPECT_NO_FATAL_FAILURE(
-      web_ui_.HandleReceivedMessage(kRecordNavigation, &args));
+      web_ui_.HandleReceivedMessage(kRecordNavigation, args));
   EXPECT_EQ(expected_view, handler_->GetCurrentViewForTesting());
 }
 
 TEST_F(DiagnosticsMetricsMessageHandlerTest, HandleRecordNavigationWithOneArg) {
-  base::ListValue args;
+  base::Value::List args;
   args.Append(base::Value(0));
 
   NavigationView expected_view = NavigationView::kSystem;
   InitializeHandler(expected_view);
 
   EXPECT_NO_FATAL_FAILURE(
-      web_ui_.HandleReceivedMessage(kRecordNavigation, &args));
+      web_ui_.HandleReceivedMessage(kRecordNavigation, args));
   EXPECT_EQ(expected_view, handler_->GetCurrentViewForTesting());
 }
 
 TEST_F(DiagnosticsMetricsMessageHandlerTest,
        HandleRecordNavigationWithInvalidArgs) {
-  base::ListValue args;
+  base::Value::List args;
   args.Append(base::Value("0"));
   args.Append(base::Value());
 
@@ -217,13 +217,13 @@
   InitializeHandler(expected_view);
 
   EXPECT_NO_FATAL_FAILURE(
-      web_ui_.HandleReceivedMessage(kRecordNavigation, &args));
+      web_ui_.HandleReceivedMessage(kRecordNavigation, args));
   EXPECT_EQ(expected_view, handler_->GetCurrentViewForTesting());
 }
 
 TEST_F(DiagnosticsMetricsMessageHandlerTest,
        HandleRecordNavigationWithMatchingArgs) {
-  base::ListValue args;
+  base::Value::List args;
   args.Append(base::Value(1));
   args.Append(base::Value(1));
 
@@ -231,13 +231,13 @@
   InitializeHandler(expected_view);
 
   EXPECT_NO_FATAL_FAILURE(
-      web_ui_.HandleReceivedMessage(kRecordNavigation, &args));
+      web_ui_.HandleReceivedMessage(kRecordNavigation, args));
   EXPECT_EQ(expected_view, handler_->GetCurrentViewForTesting());
 }
 
 TEST_F(DiagnosticsMetricsMessageHandlerTest,
        HandleRecordNavigationWithOutOfRangeArgs) {
-  base::ListValue args;
+  base::Value::List args;
   args.Append(base::Value(-100));
   args.Append(base::Value(100));
 
@@ -245,7 +245,7 @@
   InitializeHandler(expected_view);
 
   EXPECT_NO_FATAL_FAILURE(
-      web_ui_.HandleReceivedMessage(kRecordNavigation, &args));
+      web_ui_.HandleReceivedMessage(kRecordNavigation, args));
   EXPECT_EQ(expected_view, handler_->GetCurrentViewForTesting());
 }
 }  // namespace metrics
diff --git a/ash/webui/projector_app/test/annotator_message_handler_unittest.cc b/ash/webui/projector_app/test/annotator_message_handler_unittest.cc
index 8f5b3c88..4846680a 100644
--- a/ash/webui/projector_app/test/annotator_message_handler_unittest.cc
+++ b/ash/webui/projector_app/test/annotator_message_handler_unittest.cc
@@ -48,16 +48,16 @@
   }
 
   void SendUndoRedoAvailableChanged(bool undo_available, bool redo_available) {
-    base::ListValue list_args;
+    base::Value::List list_args;
     list_args.Append(base::Value(undo_available));
     list_args.Append(base::Value(redo_available));
-    web_ui().HandleReceivedMessage("onUndoRedoAvailabilityChanged", &list_args);
+    web_ui().HandleReceivedMessage("onUndoRedoAvailabilityChanged", list_args);
   }
 
   void SendCanvasInitialized(bool success) {
-    base::ListValue list_args;
+    base::Value::List list_args;
     list_args.Append(base::Value(success));
-    web_ui().HandleReceivedMessage("onCanvasInitialized", &list_args);
+    web_ui().HandleReceivedMessage("onCanvasInitialized", list_args);
   }
 
   content::TestWebUI& web_ui() { return web_ui_; }
diff --git a/ash/webui/projector_app/test/projector_message_handler_unittest.cc b/ash/webui/projector_app/test/projector_message_handler_unittest.cc
index ca6dab1c..4990e50 100644
--- a/ash/webui/projector_app/test/projector_message_handler_unittest.cc
+++ b/ash/webui/projector_app/test/projector_message_handler_unittest.cc
@@ -159,10 +159,10 @@
 };
 
 TEST_F(ProjectorMessageHandlerUnitTest, GetAccounts) {
-  base::ListValue list_args;
+  base::Value::List list_args;
   list_args.Append(kGetAccountsCallback);
 
-  web_ui().HandleReceivedMessage("getAccounts", &list_args);
+  web_ui().HandleReceivedMessage("getAccounts", list_args);
 
   // We expect that there was only one callback to the WebUI.
   EXPECT_EQ(web_ui().call_data().size(), 1u);
@@ -195,11 +195,11 @@
   ON_CALL(controller(), GetNewScreencastPrecondition)
       .WillByDefault(testing::Return(precondition));
 
-  base::ListValue list_args;
+  base::Value::List list_args;
   list_args.Append(kGetNewScreencastPreconditionCallback);
 
   web_ui().HandleReceivedMessage("getNewScreencastPreconditionState",
-                                 &list_args);
+                                 list_args);
 
   // We expect that there was only one callback to the WebUI.
   EXPECT_EQ(web_ui().call_data().size(), 1u);
@@ -217,13 +217,13 @@
 TEST_F(ProjectorMessageHandlerUnitTest, GetOAuthTokenForAccount) {
   mock_app_client().SetAutomaticIssueOfAccessTokens(false);
 
-  base::ListValue list_args;
+  base::Value::List list_args;
   list_args.Append(kGetOAuthTokenCallback);
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kTestUserEmail);
   list_args.Append(std::move(args));
 
-  web_ui().HandleReceivedMessage("getOAuthTokenForAccount", &list_args);
+  web_ui().HandleReceivedMessage("getOAuthTokenForAccount", list_args);
   mock_app_client().WaitForAccessRequest(kTestUserEmail);
 
   EXPECT_EQ(web_ui().call_data().size(), 1u);
@@ -236,9 +236,9 @@
 TEST_F(ProjectorMessageHandlerUnitTest, SendXhr) {
   const std::string& test_response_body = "{}";
 
-  base::ListValue list_args;
+  base::Value::List list_args;
   list_args.Append(kSendXhrCallback);
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kTestXhrUrl);
   args.Append(kTestXhrMethod);
   args.Append(kTestXhrRequestBody);
@@ -255,7 +255,7 @@
 
   base::RunLoop run_loop;
   message_handler()->SetXhrRequestRunLoopQuitClosure(run_loop.QuitClosure());
-  web_ui().HandleReceivedMessage("sendXhr", &list_args);
+  web_ui().HandleReceivedMessage("sendXhr", list_args);
   run_loop.Run();
 
   EXPECT_EQ(web_ui().call_data().size(), 1u);
@@ -283,9 +283,9 @@
 }
 
 TEST_F(ProjectorMessageHandlerUnitTest, SendXhrWithUnSupportedUrl) {
-  base::ListValue list_args;
+  base::Value::List list_args;
   list_args.Append(kSendXhrCallback);
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kTestXhrUnsupportedUrl);
   args.Append(kTestXhrMethod);
   args.Append(kTestXhrRequestBody);
@@ -299,7 +299,7 @@
 
   base::RunLoop run_loop;
   message_handler()->SetXhrRequestRunLoopQuitClosure(run_loop.QuitClosure());
-  web_ui().HandleReceivedMessage("sendXhr", &list_args);
+  web_ui().HandleReceivedMessage("sendXhr", list_args);
   run_loop.Run();
 
   EXPECT_EQ(web_ui().call_data().size(), 1u);
@@ -364,10 +364,10 @@
   ON_CALL(mock_app_client(), ShouldDownloadSoda())
       .WillByDefault(testing::Return(true));
 
-  base::ListValue list_args;
+  base::Value::List list_args;
   list_args.Append(base::Value(kShouldDownloadSodaCallback));
 
-  web_ui().HandleReceivedMessage("shouldDownloadSoda", &list_args);
+  web_ui().HandleReceivedMessage("shouldDownloadSoda", list_args);
 
   const content::TestWebUI::CallData& call_data = FetchCallData(0);
   EXPECT_EQ(call_data.function_name(), kWebUIResponse);
@@ -379,10 +379,10 @@
 TEST_F(ProjectorMessageHandlerUnitTest, InstallSoda) {
   ON_CALL(mock_app_client(), InstallSoda()).WillByDefault(testing::Return());
 
-  base::ListValue list_args;
+  base::Value::List list_args;
   list_args.Append(base::Value(kInstallSodaCallback));
 
-  web_ui().HandleReceivedMessage("installSoda", &list_args);
+  web_ui().HandleReceivedMessage("installSoda", list_args);
 
   const content::TestWebUI::CallData& call_data = FetchCallData(0);
   EXPECT_EQ(call_data.function_name(), kWebUIResponse);
@@ -401,10 +401,10 @@
   ON_CALL(mock_app_client(), GetPendingScreencasts())
       .WillByDefault(testing::ReturnRef(expectedScreencasts));
 
-  base::ListValue list_args;
+  base::Value::List list_args;
   list_args.Append(kGetPendingScreencastsCallback);
 
-  web_ui().HandleReceivedMessage("getPendingScreencasts", &list_args);
+  web_ui().HandleReceivedMessage("getPendingScreencasts", list_args);
 
   // We expect that there was only one callback to the WebUI.
   EXPECT_EQ(web_ui().call_data().size(), 1u);
@@ -435,15 +435,15 @@
 }
 
 TEST_F(ProjectorMessageHandlerUnitTest, CreationFlowEnabled) {
-  base::ListValue list_args;
+  base::Value::List list_args;
   list_args.Append(base::Value(kSetUserPrefCallback));
 
-  base::ListValue func_args;
+  base::Value::List func_args;
   func_args.Append(base::Value(ash::prefs::kProjectorCreationFlowEnabled));
   func_args.Append(base::Value(true));
   list_args.Append(std::move(func_args));
 
-  web_ui().HandleReceivedMessage("setUserPref", &list_args);
+  web_ui().HandleReceivedMessage("setUserPref", list_args);
 
   const content::TestWebUI::CallData& call_data = FetchCallData(0);
   EXPECT_EQ(call_data.function_name(), kWebUIResponse);
@@ -451,13 +451,13 @@
   EXPECT_EQ(call_data.arg2()->GetBool(), true);
 
   // Now let's try to read the user's pref.
-  list_args.ClearList();
+  list_args.clear();
   list_args.Append(base::Value(kGetUserPrefCallback));
-  func_args.ClearList();
+  func_args.clear();
   func_args.Append(ash::prefs::kProjectorCreationFlowEnabled);
   list_args.Append(std::move(func_args));
 
-  web_ui().HandleReceivedMessage("getUserPref", &list_args);
+  web_ui().HandleReceivedMessage("getUserPref", list_args);
 
   const content::TestWebUI::CallData& get_pref_call_data = FetchCallData(1);
   EXPECT_EQ(get_pref_call_data.function_name(), kWebUIResponse);
@@ -470,16 +470,16 @@
 }
 
 TEST_F(ProjectorMessageHandlerUnitTest, ExcludeTranscriptDialogShownPref) {
-  base::ListValue list_args;
+  base::Value::List list_args;
   list_args.Append(base::Value(kSetUserPrefCallback));
 
-  base::ListValue func_args;
+  base::Value::List func_args;
   func_args.Append(
       base::Value(ash::prefs::kProjectorExcludeTranscriptDialogShown));
   func_args.Append(base::Value(true));
   list_args.Append(std::move(func_args));
 
-  web_ui().HandleReceivedMessage("setUserPref", &list_args);
+  web_ui().HandleReceivedMessage("setUserPref", list_args);
 
   const content::TestWebUI::CallData& call_data = FetchCallData(0);
   EXPECT_EQ(call_data.function_name(), kWebUIResponse);
@@ -487,13 +487,13 @@
   EXPECT_EQ(call_data.arg2()->GetBool(), true);
 
   // Now let's try to read the user's pref.
-  list_args.ClearList();
+  list_args.clear();
   list_args.Append(base::Value(kGetUserPrefCallback));
-  func_args.ClearList();
+  func_args.clear();
   func_args.Append(ash::prefs::kProjectorExcludeTranscriptDialogShown);
   list_args.Append(std::move(func_args));
 
-  web_ui().HandleReceivedMessage("getUserPref", &list_args);
+  web_ui().HandleReceivedMessage("getUserPref", list_args);
 
   const content::TestWebUI::CallData& get_pref_call_data = FetchCallData(1);
   EXPECT_EQ(get_pref_call_data.function_name(), kWebUIResponse);
@@ -506,17 +506,17 @@
 }
 
 TEST_F(ProjectorMessageHandlerUnitTest, SetCreationFlowEnabledInvalidValue) {
-  base::ListValue list_args;
+  base::Value::List list_args;
   list_args.Append(base::Value(kSetUserPrefCallback));
 
-  base::ListValue func_args;
+  base::Value::List func_args;
   func_args.Append(ash::prefs::kProjectorCreationFlowEnabled);
 
   // The value provided is not a boolean. Therefore it will fail.
   func_args.Append(base::Value("temp"));
   list_args.Append(func_args.Clone());
 
-  web_ui().HandleReceivedMessage("setUserPref", &list_args);
+  web_ui().HandleReceivedMessage("setUserPref", list_args);
 
   const content::TestWebUI::CallData& call_data = FetchCallData(0);
   EXPECT_EQ(call_data.function_name(), kWebUIResponse);
@@ -533,10 +533,10 @@
 }
 
 TEST_F(ProjectorMessageHandlerUnitTest, OpenFeedbackDialog) {
-  base::ListValue list_args;
+  base::Value::List list_args;
   list_args.Append(base::Value(kOpenFeedbackDialogCallback));
 
-  web_ui().HandleReceivedMessage("openFeedbackDialog", &list_args);
+  web_ui().HandleReceivedMessage("openFeedbackDialog", list_args);
 
   const content::TestWebUI::CallData& call_data = FetchCallData(0);
   EXPECT_EQ(call_data.function_name(), kWebUIResponse);
@@ -544,15 +544,15 @@
 }
 
 TEST_F(ProjectorMessageHandlerUnitTest, SetCreationFlowEnabledUnsupportedPref) {
-  base::ListValue list_args;
+  base::Value::List list_args;
   list_args.Append(base::Value(kSetUserPrefCallback));
 
-  base::ListValue func_args;
+  base::Value::List func_args;
   func_args.Append("invalidUserPref");
   func_args.Append(base::Value(true));
   list_args.Append(func_args.Clone());
 
-  web_ui().HandleReceivedMessage("setUserPref", &list_args);
+  web_ui().HandleReceivedMessage("setUserPref", list_args);
 
   const content::TestWebUI::CallData& call_data = FetchCallData(0);
   EXPECT_EQ(call_data.function_name(), kWebUIResponse);
@@ -582,14 +582,14 @@
                 /*error_message=*/std::string());
           });
 
-  base::ListValue list_args;
+  base::Value::List list_args;
   list_args.Append(kGetVideoCallback);
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kVideoFileId);
   args.Append(kResourceKey);
   list_args.Append(std::move(args));
 
-  web_ui().HandleReceivedMessage("getVideo", &list_args);
+  web_ui().HandleReceivedMessage("getVideo", list_args);
 
   // We expect that there was only one callback to the WebUI.
   EXPECT_EQ(web_ui().call_data().size(), 1u);
@@ -613,14 +613,14 @@
         std::move(callback).Run(/*video=*/nullptr, /*error_message=*/"error1");
       });
 
-  base::ListValue list_args;
+  base::Value::List list_args;
   list_args.Append(kGetVideoCallback);
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kVideoFileId);
   args.Append(base::Value());
   list_args.Append(std::move(args));
 
-  web_ui().HandleReceivedMessage("getVideo", &list_args);
+  web_ui().HandleReceivedMessage("getVideo", list_args);
 
   // We expect that there was only one callback to the WebUI.
   EXPECT_EQ(web_ui().call_data().size(), 1u);
@@ -656,13 +656,13 @@
             NewScreencastPreconditionState::kEnabled, {})));
   }
 
-  base::ListValue list_args;
+  base::Value::List list_args;
   list_args.Append(kStartProjectorSessionCallback);
-  base::ListValue args;
+  base::Value::List args;
   args.Append(std::get<0>(GetParam()));
   list_args.Append(std::move(args));
 
-  web_ui().HandleReceivedMessage("startProjectorSession", &list_args);
+  web_ui().HandleReceivedMessage("startProjectorSession", list_args);
 
   // We expect that there was only one callback to the WebUI.
   EXPECT_EQ(web_ui().call_data().size(), 1u);
@@ -704,13 +704,13 @@
   EXPECT_CALL(controller(), StartProjectorSession("folderId"))
       .Times(success ? 1 : 0);
 
-  base::ListValue list_args;
+  base::Value::List list_args;
   list_args.Append(kStartProjectorSessionCallback);
-  base::ListValue args;
+  base::Value::List args;
   args.Append("folderId");
   list_args.Append(std::move(args));
 
-  web_ui().HandleReceivedMessage("startProjectorSession", &list_args);
+  web_ui().HandleReceivedMessage("startProjectorSession", list_args);
 
   // We expect that there was only one callback to the WebUI.
   EXPECT_EQ(web_ui().call_data().size(), 1u);
@@ -748,15 +748,15 @@
 
 TEST_P(ProjectorOnboardingFlowPrefTest, OnboardingFlowPrefTest) {
   // Set the user preference.
-  base::ListValue set_list_args;
+  base::Value::List set_list_args;
   set_list_args.Append(base::Value(kSetUserPrefCallback));
-  base::ListValue func_args;
+  base::Value::List func_args;
   func_args.Append(base::Value(GetParam()));
   func_args.Append(base::Value(5));
   set_list_args.Append(std::move(func_args));
 
   // Set the value of the preference passed to the test as a parameter.
-  web_ui().HandleReceivedMessage("setUserPref", &set_list_args);
+  web_ui().HandleReceivedMessage("setUserPref", set_list_args);
 
   const content::TestWebUI::CallData& set_call_data = FetchCallData(0);
   EXPECT_EQ(set_call_data.function_name(), kWebUIResponse);
@@ -766,12 +766,12 @@
   EXPECT_EQ(set_call_data.arg2()->GetBool(), true);
 
   // Fetch the pref just set
-  base::ListValue get_list_args;
+  base::Value::List get_list_args;
   get_list_args.Append(base::Value(kGetUserPrefCallback));
-  base::ListValue get_func_args;
+  base::Value::List get_func_args;
   get_func_args.Append(base::Value(GetParam()));
   get_list_args.Append(std::move(get_func_args));
-  web_ui().HandleReceivedMessage("getUserPref", &get_list_args);
+  web_ui().HandleReceivedMessage("getUserPref", get_list_args);
 
   // Check that getUserPref succeeded.
   const content::TestWebUI::CallData& get_call_data = FetchCallData(1);
diff --git a/ash/webui/scanning/scanning_handler_unittest.cc b/ash/webui/scanning/scanning_handler_unittest.cc
index 5e73a00..bf31cfd 100644
--- a/ash/webui/scanning/scanning_handler_unittest.cc
+++ b/ash/webui/scanning/scanning_handler_unittest.cc
@@ -184,8 +184,8 @@
     scanning_handler_->SetWebUIForTest(&web_ui_);
     scanning_handler_->RegisterMessages();
 
-    base::ListValue args;
-    web_ui_.HandleReceivedMessage("initialize", &args);
+    base::Value::List args;
+    web_ui_.HandleReceivedMessage("initialize", args);
 
     EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
     my_files_path_ = temp_dir_.GetPath().Append("MyFiles");
@@ -229,9 +229,9 @@
       new TestSelectFileDialogFactory(base_file_path));
 
   const size_t call_data_count_before_call = web_ui_.call_data().size();
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kHandlerFunctionName);
-  web_ui_.HandleReceivedMessage("requestScanToLocation", &args);
+  web_ui_.HandleReceivedMessage("requestScanToLocation", args);
 
   const content::TestWebUI::CallData& call_data =
       GetCallData(call_data_count_before_call);
@@ -250,9 +250,9 @@
       new TestSelectFileDialogFactory(base::FilePath()));
 
   const size_t call_data_count_before_call = web_ui_.call_data().size();
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kHandlerFunctionName);
-  web_ui_.HandleReceivedMessage("requestScanToLocation", &args);
+  web_ui_.HandleReceivedMessage("requestScanToLocation", args);
 
   const content::TestWebUI::CallData& call_data =
       GetCallData(call_data_count_before_call);
@@ -266,10 +266,10 @@
 // OpenFilesAppFunction function and returns the callback with the boolean.
 TEST_F(ScanningHandlerTest, ShowFileInLocation) {
   const size_t call_data_count_before_call = web_ui_.call_data().size();
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kHandlerFunctionName);
   args.Append(kTestFilePath);
-  web_ui_.HandleReceivedMessage("showFileInLocation", &args);
+  web_ui_.HandleReceivedMessage("showFileInLocation", args);
 
   const content::TestWebUI::CallData& call_data =
       GetCallData(call_data_count_before_call);
@@ -281,9 +281,9 @@
 // path.
 TEST_F(ScanningHandlerTest, GetMyFilesPath) {
   const size_t call_data_count_before_call = web_ui_.call_data().size();
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kHandlerFunctionName);
-  web_ui_.HandleReceivedMessage("getMyFilesPath", &args);
+  web_ui_.HandleReceivedMessage("getMyFilesPath", args);
 
   const content::TestWebUI::CallData& call_data =
       GetCallData(call_data_count_before_call);
@@ -300,9 +300,9 @@
   file_paths_value.Append(base::Value(file1));
   file_paths_value.Append(base::Value(file2));
 
-  base::ListValue args;
+  base::Value::List args;
   args.Append(std::move(file_paths_value));
-  web_ui_.HandleReceivedMessage("openFilesInMediaApp", &args);
+  web_ui_.HandleReceivedMessage("openFilesInMediaApp", args);
 
   const std::vector<base::FilePath> expected_file_paths(
       {base::FilePath(file1), base::FilePath(file2)});
@@ -330,15 +330,15 @@
   })";
 
   // First, save the expected scan settings to the Pref service.
-  base::ListValue save_args;
+  base::Value::List save_args;
   save_args.Append(expected_sticky_settings);
-  web_ui_.HandleReceivedMessage("saveScanSettings", &save_args);
+  web_ui_.HandleReceivedMessage("saveScanSettings", save_args);
 
   // Then retrieve the expected scan settings from the Pref service.
   const size_t call_data_count_before_call = web_ui_.call_data().size();
-  base::ListValue get_args;
+  base::Value::List get_args;
   get_args.Append(kHandlerFunctionName);
-  web_ui_.HandleReceivedMessage("getScanSettings", &get_args);
+  web_ui_.HandleReceivedMessage("getScanSettings", get_args);
   const content::TestWebUI::CallData& call_data =
       GetCallData(call_data_count_before_call);
   EXPECT_EQ(expected_sticky_settings, call_data.arg3()->GetString());
@@ -351,10 +351,10 @@
   base::File(myScanPath, base::File::FLAG_CREATE | base::File::FLAG_READ);
 
   const size_t call_data_count_before_call = web_ui_.call_data().size();
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kHandlerFunctionName);
   args.Append(myScanPath.value());
-  web_ui_.HandleReceivedMessage("ensureValidFilePath", &args);
+  web_ui_.HandleReceivedMessage("ensureValidFilePath", args);
   task_environment_.RunUntilIdle();
 
   const content::TestWebUI::CallData& call_data =
@@ -372,10 +372,10 @@
   const std::string invalidFilePath = "invalid/file/path";
 
   const size_t call_data_count_before_call = web_ui_.call_data().size();
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kHandlerFunctionName);
   args.Append(invalidFilePath);
-  web_ui_.HandleReceivedMessage("ensureValidFilePath", &args);
+  web_ui_.HandleReceivedMessage("ensureValidFilePath", args);
   task_environment_.RunUntilIdle();
 
   const content::TestWebUI::CallData& call_data =
@@ -389,11 +389,11 @@
 // Validates a request for a plural string with a key missing in the plural
 // string map does return a value.
 TEST_F(ScanningHandlerTest, GetPluralStringBadKey) {
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kHandlerFunctionName);
   args.Append(/*name=*/"incorrectKey");
   args.Append(/*count=*/2);
-  web_ui_.HandleReceivedMessage("getPluralString", &args);
+  web_ui_.HandleReceivedMessage("getPluralString", args);
   task_environment_.RunUntilIdle();
 
   const std::vector<std::unique_ptr<content::TestWebUI::CallData>>&
diff --git a/base/message_loop/message_pump_libevent.cc b/base/message_loop/message_pump_libevent.cc
index 3d090ba..f5b612d1 100644
--- a/base/message_loop/message_pump_libevent.cc
+++ b/base/message_loop/message_pump_libevent.cc
@@ -137,7 +137,7 @@
   watcher_->OnFileCanWriteWithoutBlocking(epoll_interest_->params().fd);
 }
 
-MessagePumpLibevent::MessagePumpLibevent() : event_base_(event_base_new()) {
+MessagePumpLibevent::MessagePumpLibevent() {
 #if BUILDFLAG(ENABLE_MESSAGE_PUMP_EPOLL)
   if (g_use_epoll) {
     epoll_pump_ = std::make_unique<MessagePumpEpoll>();
@@ -154,8 +154,7 @@
 
 #if BUILDFLAG(ENABLE_MESSAGE_PUMP_EPOLL)
 MessagePumpLibevent::MessagePumpLibevent(decltype(kUseEpoll))
-    : epoll_pump_(std::make_unique<MessagePumpEpoll>()),
-      event_base_(event_base_new()) {
+    : epoll_pump_(std::make_unique<MessagePumpEpoll>()) {
   epoll_pump_ = std::make_unique<MessagePumpEpoll>();
 }
 #endif
@@ -170,8 +169,8 @@
   DCHECK(event_base_);
   if (using_libevent) {
     DCHECK(wakeup_event_);
-    event_del(wakeup_event_);
-    delete wakeup_event_;
+    event_del(wakeup_event_.get());
+    wakeup_event_.reset();
     if (wakeup_pipe_in_ >= 0) {
       if (IGNORE_EINTR(close(wakeup_pipe_in_)) < 0)
         DPLOG(ERROR) << "close";
@@ -181,7 +180,7 @@
         DPLOG(ERROR) << "close";
     }
   }
-  event_base_free(event_base_);
+  event_base_.reset();
 }
 
 // Must be called early in process startup, but after FeatureList
@@ -251,7 +250,7 @@
   event_set(evt.get(), fd, event_mask, OnLibeventNotification, controller);
 
   // Tell libevent which message pump this socket will belong to when we add it.
-  if (event_base_set(event_base_, evt.get())) {
+  if (event_base_set(event_base_.get(), evt.get())) {
     DPLOG(ERROR) << "event_base_set(fd=" << EVENT_FD(evt.get()) << ")";
     return false;
   }
@@ -313,7 +312,7 @@
     //    OnLibeventNotification() did enter a nested loop from here, it
     //    wouldn't be labeled as such in tracing by "ThreadController active".
     //    Contact gab@/scheduler-dev@ if a problematic trace emerges.
-    event_base_loop(event_base_, EVLOOP_NONBLOCK);
+    event_base_loop(event_base_.get(), EVLOOP_NONBLOCK);
 
     bool attempt_more_work = immediate_work_available || processed_io_events_;
     processed_io_events_ = false;
@@ -343,8 +342,8 @@
       struct timeval poll_tv;
       poll_tv.tv_sec = static_cast<time_t>(delay.InSeconds());
       poll_tv.tv_usec = delay.InMicroseconds() % Time::kMicrosecondsPerSecond;
-      event_set(timer_event.get(), -1, 0, timer_callback, event_base_);
-      event_base_set(event_base_, timer_event.get());
+      event_set(timer_event.get(), -1, 0, timer_callback, event_base_.get());
+      event_base_set(event_base_.get(), timer_event.get());
       event_add(timer_event.get(), &poll_tv);
 
       did_set_timer = true;
@@ -354,7 +353,7 @@
     // is conditionally interrupted to look for more work if we are aware of a
     // delayed task that will need servicing.
     delegate->BeforeWait();
-    event_base_loop(event_base_, EVLOOP_ONCE);
+    event_base_loop(event_base_.get(), EVLOOP_ONCE);
 
     // We previously setup a timer to break out the event loop to look for more
     // work. Now that we're here delete the event.
@@ -413,12 +412,12 @@
   wakeup_pipe_out_ = fds[0];
   wakeup_pipe_in_ = fds[1];
 
-  wakeup_event_ = new event;
-  event_set(wakeup_event_, wakeup_pipe_out_, EV_READ | EV_PERSIST,
+  wakeup_event_ = std::make_unique<event>();
+  event_set(wakeup_event_.get(), wakeup_pipe_out_, EV_READ | EV_PERSIST,
             OnWakeup, this);
-  event_base_set(event_base_, wakeup_event_);
+  event_base_set(event_base_.get(), wakeup_event_.get());
 
-  if (event_add(wakeup_event_, nullptr))
+  if (event_add(wakeup_event_.get(), nullptr))
     return false;
   return true;
 }
@@ -479,7 +478,7 @@
   DCHECK_EQ(nread, 1);
   that->processed_io_events_ = true;
   // Tell libevent to break out of inner loop.
-  event_base_loopbreak(that->event_base_);
+  event_base_loopbreak(that->event_base_.get());
 }
 
 MessagePumpLibevent::EpollInterest::EpollInterest(
diff --git a/base/message_loop/message_pump_libevent.h b/base/message_loop/message_pump_libevent.h
index 75294e0..75d76418 100644
--- a/base/message_loop/message_pump_libevent.h
+++ b/base/message_loop/message_pump_libevent.h
@@ -16,11 +16,11 @@
 #include "base/message_loop/message_pump_buildflags.h"
 #include "base/message_loop/watchable_io_message_pump_posix.h"
 #include "base/threading/thread_checker.h"
+#include "third_party/libevent/event.h"
 
 // Declare structs we need from libevent.h rather than including it
 struct event_base;
 struct event;
-
 namespace base {
 
 class MessagePumpEpoll;
@@ -220,16 +220,22 @@
   // This flag is set if libevent has processed I/O events.
   bool processed_io_events_ = false;
 
+  struct EventBaseFree {
+    inline void operator()(event_base* e) const {
+      if (e)
+        event_base_free(e);
+    }
+  };
   // Libevent dispatcher.  Watches all sockets registered with it, and sends
   // readiness callbacks when a socket is ready for I/O.
-  const raw_ptr<event_base, DanglingUntriaged> event_base_;
+  std::unique_ptr<event_base, EventBaseFree> event_base_{event_base_new()};
 
   // ... write end; ScheduleWork() writes a single byte to it
   int wakeup_pipe_in_ = -1;
   // ... read end; OnWakeup reads it and then breaks Run() out of its sleep
   int wakeup_pipe_out_ = -1;
   // ... libevent wrapper for read end
-  raw_ptr<event, DanglingUntriaged> wakeup_event_ = nullptr;
+  std::unique_ptr<event> wakeup_event_;
 
   ThreadChecker watch_file_descriptor_caller_checker_;
 };
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1
index 56c3acc..8ef90c7 100644
--- a/build/fuchsia/linux_internal.sdk.sha1
+++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@
-9.20220810.1.1
+9.20220811.0.1
diff --git a/cc/paint/paint_op_buffer.cc b/cc/paint/paint_op_buffer.cc
index 17c9f42..475cf1c 100644
--- a/cc/paint/paint_op_buffer.cc
+++ b/cc/paint/paint_op_buffer.cc
@@ -120,14 +120,6 @@
   return false;
 }
 
-class ThreadsafePath : public SkPath {
- public:
-  explicit ThreadsafePath(const SkPath& path) : SkPath(path) {
-    updateBoundsCache();
-  }
-  ThreadsafePath() { updateBoundsCache(); }
-};
-
 }  // namespace
 
 #define TYPES(M)      \
@@ -469,7 +461,7 @@
                              const SkM44& original_ctm) {
   auto* op = static_cast<const ClipPathOp*>(base_op);
   PaintOpWriter helper(memory, size, options);
-  helper.Write(*op->path, op->use_cache);
+  helper.Write(op->path, op->use_cache);
   helper.Write(op->op);
   helper.Write(op->antialias);
   return helper.size();
@@ -685,7 +677,7 @@
   if (!flags_to_serialize)
     flags_to_serialize = &op->flags;
   helper.Write(*flags_to_serialize, current_ctm);
-  helper.Write(*op->path, op->use_cache);
+  helper.Write(op->path, op->use_cache);
   helper.Write(op->sk_path_fill_type);
   return helper.size();
 }
@@ -1056,7 +1048,7 @@
   PaintOpDeserializer<ClipPathOp> deserializer(input, input_size, options,
                                                new (output) ClipPathOp);
 
-  deserializer.Read(deserializer->path.get());
+  deserializer.Read(&deserializer->path);
   deserializer.Read(&deserializer->op);
   deserializer.Read(&deserializer->antialias);
   return deserializer.FinalizeOp();
@@ -1236,9 +1228,9 @@
   PaintOpDeserializer<DrawPathOp> deserializer(input, input_size, options,
                                                new (output) DrawPathOp);
   deserializer.Read(&deserializer->flags);
-  deserializer.Read(deserializer->path.get());
+  deserializer.Read(&deserializer->path);
   deserializer.Read(&deserializer->sk_path_fill_type);
-  deserializer->path->setFillType(
+  deserializer->path.setFillType(
       static_cast<SkPathFillType>(deserializer->sk_path_fill_type));
   return deserializer.FinalizeOp();
 }
@@ -1545,7 +1537,7 @@
 void ClipPathOp::Raster(const ClipPathOp* op,
                         SkCanvas* canvas,
                         const PlaybackParams& params) {
-  canvas->clipPath(*op->path, op->op, op->antialias);
+  canvas->clipPath(op->path, op->op, op->antialias);
 }
 
 void ClipRectOp::Raster(const ClipRectOp* op,
@@ -1561,8 +1553,8 @@
 }
 
 void ConcatOp::Raster(const ConcatOp* op,
-                      SkCanvas* canvas,
-                      const PlaybackParams& params) {
+                        SkCanvas* canvas,
+                        const PlaybackParams& params) {
   canvas->concat(op->matrix);
 }
 
@@ -1760,7 +1752,7 @@
                                  SkCanvas* canvas,
                                  const PlaybackParams& params) {
   flags->DrawToSk(canvas, [op](SkCanvas* c, const SkPaint& p) {
-    c->drawPath(*op->path, p);
+    c->drawPath(op->path, p);
   });
 }
 
@@ -1939,8 +1931,8 @@
 }
 
 void SetMatrixOp::Raster(const SetMatrixOp* op,
-                         SkCanvas* canvas,
-                         const PlaybackParams& params) {
+                           SkCanvas* canvas,
+                           const PlaybackParams& params) {
   canvas->setMatrix(params.original_ctm * op->matrix);
 }
 
@@ -2073,7 +2065,7 @@
   auto* right = static_cast<const ClipPathOp*>(base_right);
   DCHECK(left->IsValid());
   DCHECK(right->IsValid());
-  if (*left->path != *right->path)
+  if (left->path != right->path)
     return false;
   if (left->op != right->op)
     return false;
@@ -2240,7 +2232,7 @@
   DCHECK(right->IsValid());
   if (left->flags != right->flags)
     return false;
-  if (*left->path != *right->path)
+  if (left->path != right->path)
     return false;
   return true;
 }
@@ -2555,7 +2547,7 @@
     }
     case PaintOpType::DrawPath: {
       auto* path_op = static_cast<const DrawPathOp*>(op);
-      *rect = path_op->path->getBounds();
+      *rect = path_op->path.getBounds();
       rect->sort();
       return true;
     }
@@ -2706,7 +2698,7 @@
 }
 
 int ClipPathOp::CountSlowPaths() const {
-  return antialias && !path->isConvex() ? 1 : 0;
+  return antialias && !path.isConvex() ? 1 : 0;
 }
 
 int DrawLineOp::CountSlowPaths() const {
@@ -2726,17 +2718,17 @@
 int DrawPathOp::CountSlowPaths() const {
   // This logic is copied from SkPathCounter instead of attempting to expose
   // that from Skia.
-  if (!flags.isAntiAlias() || path->isConvex())
+  if (!flags.isAntiAlias() || path.isConvex())
     return 0;
 
   PaintFlags::Style paintStyle = flags.getStyle();
-  const SkRect& pathBounds = path->getBounds();
+  const SkRect& pathBounds = path.getBounds();
   if (paintStyle == PaintFlags::kStroke_Style && flags.getStrokeWidth() == 0) {
     // AA hairline concave path is not slow.
     return 0;
   } else if (paintStyle == PaintFlags::kFill_Style &&
              pathBounds.width() < 64.f && pathBounds.height() < 64.f &&
-             !path->isVolatile()) {
+             !path.isVolatile()) {
     // AADF eligible concave path is not slow.
     return 0;
   } else {
@@ -2780,23 +2772,6 @@
 
 AnnotateOp::~AnnotateOp() = default;
 
-ClipPathOp::ClipPathOp()
-    : PaintOp(kType), path(std::make_unique<ThreadsafePath>()) {}
-
-ClipPathOp::ClipPathOp(SkPath path,
-                       SkClipOp op,
-                       bool antialias,
-                       UsePaintCache use_paint_cache)
-    : PaintOp(kType),
-      path(std::make_unique<ThreadsafePath>(path)),
-      op(op),
-      antialias(antialias),
-      use_cache(use_paint_cache) {}
-
-ClipPathOp::ClipPathOp(ClipPathOp&&) = default;
-
-ClipPathOp::~ClipPathOp() = default;
-
 DrawImageOp::DrawImageOp() : PaintOpWithFlags(kType) {}
 
 DrawImageOp::DrawImageOp(const PaintImage& image, SkScalar left, SkScalar top)
@@ -2855,21 +2830,6 @@
 
 DrawImageRectOp::~DrawImageRectOp() = default;
 
-DrawPathOp::DrawPathOp()
-    : PaintOpWithFlags(kType), path(std::make_unique<ThreadsafePath>()) {}
-
-DrawPathOp::DrawPathOp(const SkPath& path,
-                       const PaintFlags& flags,
-                       UsePaintCache use_paint_cache)
-    : PaintOpWithFlags(kType, flags),
-      path(std::make_unique<ThreadsafePath>(path)),
-      sk_path_fill_type(static_cast<uint8_t>(path.getFillType())),
-      use_cache(use_paint_cache) {}
-
-DrawPathOp::DrawPathOp(DrawPathOp&&) = default;
-
-DrawPathOp::~DrawPathOp() = default;
-
 DrawRecordOp::DrawRecordOp(sk_sp<const PaintRecord> record)
     : PaintOp(kType), record(std::move(record)) {}
 
diff --git a/cc/paint/paint_op_buffer.h b/cc/paint/paint_op_buffer.h
index d0a7b24..fbb5b96 100644
--- a/cc/paint/paint_op_buffer.h
+++ b/cc/paint/paint_op_buffer.h
@@ -57,6 +57,14 @@
 class TransferCacheDeserializeHelper;
 class TransferCacheSerializeHelper;
 
+class CC_PAINT_EXPORT ThreadsafePath : public SkPath {
+ public:
+  explicit ThreadsafePath(const SkPath& path) : SkPath(path) {
+    updateBoundsCache();
+  }
+  ThreadsafePath() { updateBoundsCache(); }
+};
+
 class CC_PAINT_EXPORT SharedImageProvider {
  public:
   enum class Error {
@@ -408,25 +416,28 @@
   ClipPathOp(SkPath path,
              SkClipOp op,
              bool antialias,
-             UsePaintCache use_paint_cache = UsePaintCache::kEnabled);
-  ClipPathOp(ClipPathOp&&);
-  ~ClipPathOp();
+             UsePaintCache use_paint_cache = UsePaintCache::kEnabled)
+      : PaintOp(kType),
+        path(path),
+        op(op),
+        antialias(antialias),
+        use_cache(use_paint_cache) {}
   static void Raster(const ClipPathOp* op,
                      SkCanvas* canvas,
                      const PlaybackParams& params);
-  bool IsValid() const { return IsValidSkClipOp(op) && IsValidPath(*path); }
+  bool IsValid() const { return IsValidSkClipOp(op) && IsValidPath(path); }
   static bool AreEqual(const PaintOp* left, const PaintOp* right);
   int CountSlowPaths() const;
   bool HasNonAAPaint() const { return !antialias; }
   HAS_SERIALIZATION_FUNCTIONS();
 
-  std::unique_ptr<SkPath> path;
+  ThreadsafePath path;
   SkClipOp op;
   bool antialias;
   UsePaintCache use_cache;
 
  private:
-  ClipPathOp();
+  ClipPathOp() : PaintOp(kType) {}
 };
 
 class CC_PAINT_EXPORT ClipRectOp final : public PaintOp {
@@ -708,19 +719,21 @@
   static constexpr bool kIsDrawOp = true;
   DrawPathOp(const SkPath& path,
              const PaintFlags& flags,
-             UsePaintCache use_paint_cache = UsePaintCache::kEnabled);
-  DrawPathOp(DrawPathOp&&);
-  ~DrawPathOp();
+             UsePaintCache use_paint_cache = UsePaintCache::kEnabled)
+      : PaintOpWithFlags(kType, flags),
+        path(path),
+        sk_path_fill_type(static_cast<uint8_t>(path.getFillType())),
+        use_cache(use_paint_cache) {}
   static void RasterWithFlags(const DrawPathOp* op,
                               const PaintFlags* flags,
                               SkCanvas* canvas,
                               const PlaybackParams& params);
-  bool IsValid() const { return flags.IsValid() && IsValidPath(*path); }
+  bool IsValid() const { return flags.IsValid() && IsValidPath(path); }
   static bool AreEqual(const PaintOp* left, const PaintOp* right);
   int CountSlowPaths() const;
   HAS_SERIALIZATION_FUNCTIONS();
 
-  std::unique_ptr<SkPath> path;
+  ThreadsafePath path;
 
   // Changing the fill type on an SkPath does not change the
   // generation id. This can lead to caching issues so we explicitly
@@ -730,7 +743,7 @@
   UsePaintCache use_cache;
 
  private:
-  DrawPathOp();
+  DrawPathOp() : PaintOpWithFlags(kType) {}
 };
 
 class CC_PAINT_EXPORT DrawRecordOp final : public PaintOp {
diff --git a/cc/paint/paint_op_buffer_unittest.cc b/cc/paint/paint_op_buffer_unittest.cc
index 615a06ec..9c54c44c 100644
--- a/cc/paint/paint_op_buffer_unittest.cc
+++ b/cc/paint/paint_op_buffer_unittest.cc
@@ -2827,7 +2827,7 @@
     auto* op = static_cast<DrawPathOp*>(base_op);
 
     ASSERT_TRUE(PaintOp::GetBounds(op, &rect));
-    EXPECT_EQ(rect, op->path->getBounds().makeSorted());
+    EXPECT_EQ(rect, op->path.getBounds().makeSorted());
   }
 }
 
diff --git a/cc/test/paint_op_helper.h b/cc/test/paint_op_helper.h
index 937bb294..dec1af2 100644
--- a/cc/test/paint_op_helper.h
+++ b/cc/test/paint_op_helper.h
@@ -35,7 +35,7 @@
       }
       case PaintOpType::ClipPath: {
         const auto* op = static_cast<const ClipPathOp*>(base_op);
-        str << "ClipPathOp(path=" << PaintOpHelper::SkiaTypeToString(*op->path)
+        str << "ClipPathOp(path=" << PaintOpHelper::SkiaTypeToString(op->path)
             << ", op=" << PaintOpHelper::SkiaTypeToString(op->op)
             << ", antialias=" << op->antialias
             << ", use_cache=" << (op->use_cache == UsePaintCache::kEnabled)
@@ -125,7 +125,7 @@
       }
       case PaintOpType::DrawPath: {
         const auto* op = static_cast<const DrawPathOp*>(base_op);
-        str << "DrawPathOp(path=" << PaintOpHelper::SkiaTypeToString(*op->path)
+        str << "DrawPathOp(path=" << PaintOpHelper::SkiaTypeToString(op->path)
             << ", flags=" << PaintOpHelper::FlagsToString(op->flags)
             << ", use_cache=" << (op->use_cache == UsePaintCache::kEnabled)
             << ")";
@@ -358,6 +358,10 @@
     return data ? "<SkData>" : "(nil)";
   }
 
+  static std::string SkiaTypeToString(const ThreadsafePath& path) {
+    return SkiaTypeToString(static_cast<const SkPath&>(path));
+  }
+
   static std::string SkiaTypeToString(const SkPath& path) {
     // TODO(vmpstr): SkPath has a dump function which we can use here?
     return "<SkPath>";
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index fed5085..69681ce 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -1592,6 +1592,8 @@
     "//chrome/browser/preferences:java",
     "//chrome/browser/prefetch/android:java",
     "//chrome/browser/prefetch/android:javatests",
+    "//chrome/browser/privacy_guide/android:java",
+    "//chrome/browser/privacy_guide/android:javatests",
     "//chrome/browser/privacy_sandbox/android:java",
     "//chrome/browser/privacy_sandbox/android:javatests",
     "//chrome/browser/profiles/android:java",
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantGenericUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantGenericUiTest.java
index 466b10d4..d37907af 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantGenericUiTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantGenericUiTest.java
@@ -160,6 +160,7 @@
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.autofill_assistant.R;
 import org.chromium.components.autofill_assistant.generic_ui.AssistantDimension;
+import org.chromium.ui.test.util.UiDisableIf;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -2682,6 +2683,7 @@
      */
     @Test
     @MediumTest
+    @DisableIf.Device(type = {UiDisableIf.TABLET}) // https://crbug.com/1350993
     public void testElementCondition() throws Exception {
         List<InteractionProto> interactions = new ArrayList<>();
 
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/InCctTriggeringFromGsaTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/InCctTriggeringFromGsaTest.java
index 968aeb1..a4e0c41 100644
--- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/InCctTriggeringFromGsaTest.java
+++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/InCctTriggeringFromGsaTest.java
@@ -153,7 +153,7 @@
         waitUntilViewMatchesCondition(withText("TriggerScript"), isDisplayed());
     }
     /**
-     * Tests a simple trigger heuristic that checks URLs for the appearance of https://cowin.gov.in.
+     * Tests a simple trigger heuristic that checks URL for the appearance of cart.
      *
      * {
      *   "intent":"COWIN_VACCINATION",
@@ -164,7 +164,8 @@
      *       }
      *     }
      *   ],
-     *   "enabledInCustomTabs:true,
+     *   "enabledInCustomTabs":true,
+     *   "enabledForSignedOutUsers":true
      * }
      */
     @Test
diff --git a/chrome/android/java/res/xml/privacy_preferences.xml b/chrome/android/java/res/xml/privacy_preferences.xml
index 22ab317..c12fc12 100644
--- a/chrome/android/java/res/xml/privacy_preferences.xml
+++ b/chrome/android/java/res/xml/privacy_preferences.xml
@@ -14,7 +14,8 @@
     <Preference
         android:key="privacy_guide"
         android:title="@string/prefs_privacy_guide_title"
-        android:summary="@string/prefs_privacy_guide_summary"/>
+        android:summary="@string/prefs_privacy_guide_summary"
+        android:fragment="org.chromium.chrome.browser.privacy_guide.PrivacyGuideFragment"/>
     <Preference
         android:key="safe_browsing"
         android:title="@string/prefs_safe_browsing_title"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java
index e1153d7d..3930016 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/IntentHandler.java
@@ -929,6 +929,18 @@
      * @return true if the intent should be ignored.
      */
     public boolean shouldIgnoreIntent(Intent intent, boolean startedActivity) {
+        return shouldIgnoreIntent(intent, startedActivity, /*isCustomTab=*/false);
+    }
+
+    /**
+     * Returns true if the app should ignore a given intent.
+     *
+     * @param intent Intent to check.
+     * @param startedActivity True if the Activity was not running prior to receiving the Intent.
+     * @param isCustomTab True if the Intent will end up in a Custom Tab.
+     * @return true if the intent should be ignored.
+     */
+    public boolean shouldIgnoreIntent(Intent intent, boolean startedActivity, boolean isCustomTab) {
         // Although not documented to, many/most methods that retrieve values from an Intent may
         // throw. Because we can't control what packages might send to us, we should catch any
         // Throwable and then fail closed (safe). This is ugly, but resolves top crashers in the
@@ -944,18 +956,8 @@
             boolean isInternal = notSecureIsIntentChromeOrFirstParty(intent);
             boolean isFromChrome = wasIntentSenderChrome(intent);
 
-            // "Open new incognito tab" is currently limited to Chrome.
-            //
-            // The pending incognito URL check is to handle the case where the user is shown an
-            // Android intent picker while in incognito and they select the current Chrome instance
-            // from the list.  In this case, we do not apply our Chrome token as the user has the
-            // option to select apps outside of our control, so we rely on this in memory check
-            // instead.
-            if (!isFromChrome
-                    && IntentUtils.safeGetBooleanExtra(
-                            intent, EXTRA_OPEN_NEW_INCOGNITO_TAB, false)
-                    && (getPendingIncognitoUrl() == null
-                            || !getPendingIncognitoUrl().equals(intent.getDataString()))) {
+            if (IntentUtils.safeGetBooleanExtra(intent, EXTRA_OPEN_NEW_INCOGNITO_TAB, false)
+                    && !isAllowedIncognitoIntent(isFromChrome, isCustomTab, intent)) {
                 return true;
             }
 
@@ -999,6 +1001,22 @@
         }
     }
 
+    private static boolean isAllowedIncognitoIntent(
+            boolean isChrome, boolean isCustomTab, Intent intent) {
+        // "Open new incognito tab" is currently limited to Chrome for the Chrome app. It can be
+        // launched by external apps if it's a Custom Tab, although there are additional checks in
+        // IncognitoCustomTabIntentDataProvider#isValidIncognitoIntent.
+        if (isChrome || isCustomTab) return true;
+
+        // The pending incognito URL check is to handle the case where the user is shown an
+        // Android intent picker while in incognito and they select the current Chrome instance
+        // from the list.  In this case, we do not apply our Chrome token as the user has the
+        // option to select apps outside of our control, so we rely on this in memory check
+        // instead.
+        String pendingUrl = getPendingIncognitoUrl();
+        return pendingUrl != null && pendingUrl.equals(intent.getDataString());
+    }
+
     private static boolean intentHasUnsafeInternalScheme(String scheme, String url, Intent intent) {
         if (scheme != null
                 && (intent.hasCategory(Intent.CATEGORY_BROWSABLE)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java b/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java
index 9e4a867..1a5c7542 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDispatcher.java
@@ -115,8 +115,11 @@
     public static @Action int dispatchToCustomTabActivity(Activity currentActivity, Intent intent) {
         LaunchIntentDispatcher dispatcher = new LaunchIntentDispatcher(currentActivity, intent);
         if (!isCustomTabIntent(dispatcher.mIntent)) return Action.CONTINUE;
-        dispatcher.launchCustomTabActivity();
-        return Action.FINISH_ACTIVITY;
+        if (dispatcher.launchCustomTabActivity(new IntentHandler(currentActivity, dispatcher))) {
+            return Action.FINISH_ACTIVITY;
+        } else {
+            return Action.CONTINUE;
+        }
     }
 
     private LaunchIntentDispatcher(Activity activity, Intent intent) {
@@ -187,7 +190,7 @@
 
         // Check if we should launch a Custom Tab.
         if (isCustomTabIntent) {
-            launchCustomTabActivity();
+            launchCustomTabActivity(intentHandler);
             return Action.FINISH_ACTIVITY;
         }
 
@@ -347,17 +350,24 @@
 
     /**
      * Handles launching a {@link CustomTabActivity}, which will sit on top of a client's activity
-     * in the same task.
+     * in the same task. Returns whether an Activity was launched (or brought to the foreground).
      */
-    private void launchCustomTabActivity() {
+    private boolean launchCustomTabActivity(IntentHandler intentHandler) {
         CustomTabsConnection.getInstance().onHandledIntent(
                 CustomTabsSessionToken.getSessionTokenFromIntent(mIntent), mIntent);
+
+        boolean startedActivity = false;
+        boolean isCustomTab = true;
+        if (intentHandler.shouldIgnoreIntent(mIntent, startedActivity, isCustomTab)) {
+            return false;
+        }
+
         if (!clearTopIntentsForCustomTabsEnabled(mIntent)) {
             // The old way of delivering intents relies on calling the activity directly via a
             // static reference. It doesn't allow using CLEAR_TOP, and also doesn't work when an
             // intent brings the task to foreground. The condition above is a temporary safety net.
             boolean handled = getSessionDataHolder().handleIntent(mIntent);
-            if (handled) return;
+            if (handled) return true;
         }
         maybePrefetchDnsInBackground();
 
@@ -372,10 +382,11 @@
         // Samsung devices, see https://crbug.com/796548.
         try (StrictModeContext ignored = StrictModeContext.allowDiskWrites()) {
             if (TwaSplashController.handleIntent(mActivity, launchIntent)) {
-                return;
+                return true;
             }
 
             mActivity.startActivity(launchIntent, null);
+            return true;
         }
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
index 72310c7c..ece8e6e6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -1267,7 +1267,9 @@
 
         super.onNewIntentWithNative(intent);
         getLaunchCauseMetrics().onReceivedIntent();
-        if (mIntentHandler.shouldIgnoreIntent(intent, /*startedActivity=*/false)) return;
+        if (mIntentHandler.shouldIgnoreIntent(intent, /*startedActivity=*/false, isCustomTab())) {
+            return;
+        }
 
         // We send this intent so that we can enter WebVr presentation mode if needed. This
         // call doesn't consume the intent because it also has the url that we need to load.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
index b43669d..fd13d1b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
@@ -186,8 +186,9 @@
                 ModuleFactoryOverrides.getOverrideFor(BaseCustomTabActivityModule.Factory.class);
 
         // mIntentHandler comes from the base class.
-        IntentIgnoringCriterion intentIgnoringCriterion =
-                (intent) -> mIntentHandler.shouldIgnoreIntent(intent, /*startedActivity=*/true);
+        IntentIgnoringCriterion intentIgnoringCriterion = (intent)
+                -> mIntentHandler.shouldIgnoreIntent(
+                        intent, /*startedActivity=*/true, isCustomTab());
 
         BaseCustomTabActivityModule baseCustomTabsModule = overridenBaseCustomTabFactory != null
                 ? overridenBaseCustomTabFactory.create(mIntentDataProvider,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoAboutThisSiteController.java b/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoAboutThisSiteController.java
index 057bb5d..aafa3917 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoAboutThisSiteController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoAboutThisSiteController.java
@@ -4,6 +4,7 @@
 
 package org.chromium.chrome.browser.page_info;
 
+import android.content.res.Resources;
 import android.net.Uri;
 import android.view.View;
 import android.view.ViewGroup;
@@ -129,8 +130,10 @@
         boolean more_info_enabled =
                 ChromeFeatureList.isEnabled(ChromeFeatureList.PAGE_INFO_ABOUT_THIS_SITE_MORE_INFO);
 
-        assert mSiteInfo.hasDescription();
-        String subtitle = mSiteInfo.getDescription().getDescription();
+        Resources resources = mRowView.getContext().getResources();
+        String subtitle = mSiteInfo.hasDescription()
+                ? mSiteInfo.getDescription().getDescription()
+                : resources.getString(R.string.page_info_about_this_page_description_placeholder);
         PageInfoRowView.ViewParams rowParams = new PageInfoRowView.ViewParams();
         rowParams.title = getTitle();
         rowParams.subtitle = subtitle;
@@ -139,10 +142,7 @@
         rowParams.iconResId =
                 more_info_enabled ? R.drawable.ic_globe_24dp : R.drawable.ic_info_outline_grey_24dp;
         rowParams.decreaseIconSize = true;
-        rowParams.clickCallback = more_info_enabled ? ()
-                -> openUrl(mSiteInfo.getMoreAbout().getUrl(),
-                        PageInfoAction.PAGE_INFO_ABOUT_THIS_SITE_PAGE_OPENED)
-                : this::launchSubpage;
+        rowParams.clickCallback = this::onAboutThisSiteRowClicked;
         mRowView.setParams(rowParams);
     }
 
@@ -166,6 +166,18 @@
         }
         return info;
     }
+
+    private void onAboutThisSiteRowClicked() {
+        if (ChromeFeatureList.isEnabled(ChromeFeatureList.PAGE_INFO_ABOUT_THIS_SITE_MORE_INFO)) {
+            openUrl(mSiteInfo.getMoreAbout().getUrl(),
+                    PageInfoAction.PAGE_INFO_ABOUT_THIS_SITE_PAGE_OPENED);
+        } else {
+            launchSubpage();
+        }
+        PageInfoAboutThisSiteControllerJni.get().onAboutThisSiteRowClicked(
+                mSiteInfo.hasDescription());
+    }
+
     @Override
     public void clearData() {}
 
@@ -181,5 +193,6 @@
     interface Natives {
         boolean isFeatureEnabled();
         byte[] getSiteInfo(BrowserContextHandle browserContext, GURL url, WebContents webContents);
+        void onAboutThisSiteRowClicked(boolean withDescription);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
index d79d25b..5322bb6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
@@ -10,7 +10,6 @@
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
-import android.view.ViewGroup;
 
 import androidx.preference.Preference;
 import androidx.preference.PreferenceFragmentCompat;
@@ -23,7 +22,6 @@
 import org.chromium.chrome.browser.preferences.Pref;
 import org.chromium.chrome.browser.prefetch.settings.PreloadPagesSettingsFragment;
 import org.chromium.chrome.browser.privacy.secure_dns.SecureDnsSettings;
-import org.chromium.chrome.browser.privacy_guide.PrivacyGuideDialog;
 import org.chromium.chrome.browser.privacy_sandbox.PrivacySandboxBridge;
 import org.chromium.chrome.browser.privacy_sandbox.PrivacySandboxReferrer;
 import org.chromium.chrome.browser.privacy_sandbox.PrivacySandboxSettingsFragment;
@@ -37,7 +35,6 @@
 import org.chromium.chrome.browser.sync.settings.GoogleServicesSettings;
 import org.chromium.chrome.browser.sync.settings.ManageSyncSettings;
 import org.chromium.chrome.browser.usage_stats.UsageStatsConsentDialog;
-import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.components.browser_ui.settings.ChromeSwitchPreference;
 import org.chromium.components.browser_ui.settings.ManagedPreferenceDelegate;
 import org.chromium.components.browser_ui.settings.SettingsLauncher;
@@ -68,8 +65,6 @@
 
     private ManagedPreferenceDelegate mManagedPreferenceDelegate;
     private IncognitoLockSettings mIncognitoLockSettings;
-    private ViewGroup mDialogContainer;
-    private BottomSheetController mBottomSheetController;
 
     @Override
     public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
@@ -96,14 +91,6 @@
         Preference privacyGuidePreference = findPreference(PREF_PRIVACY_GUIDE);
         if (!ChromeFeatureList.isEnabled(ChromeFeatureList.PRIVACY_GUIDE)) {
             getPreferenceScreen().removePreference(privacyGuidePreference);
-        } else {
-            // Display the privacy guide dialog when the menu item is clicked.
-            privacyGuidePreference.setOnPreferenceClickListener(preference -> {
-                PrivacyGuideDialog dialog = new PrivacyGuideDialog(
-                        getContext(), mDialogContainer, mBottomSheetController);
-                dialog.show();
-                return true;
-            });
         }
 
         IncognitoReauthSettingSwitchPreference incognitoReauthPreference =
@@ -284,12 +271,4 @@
         }
         return false;
     }
-
-    public void setDialogContainer(ViewGroup dialogContainer) {
-        mDialogContainer = dialogContainer;
-    }
-
-    public void setBottomSheetController(BottomSheetController controller) {
-        mBottomSheetController = controller;
-    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java
index aa63a08..fbf6d9de 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java
@@ -48,7 +48,7 @@
 import org.chromium.chrome.browser.password_check.PasswordCheckFragmentView;
 import org.chromium.chrome.browser.password_entry_edit.CredentialEditUiFactory;
 import org.chromium.chrome.browser.password_entry_edit.CredentialEntryFragmentViewBase;
-import org.chromium.chrome.browser.privacy.settings.PrivacySettings;
+import org.chromium.chrome.browser.privacy_guide.PrivacyGuideFragment;
 import org.chromium.chrome.browser.privacy_sandbox.AdMeasurementFragment;
 import org.chromium.chrome.browser.privacy_sandbox.AdPersonalizationFragment;
 import org.chromium.chrome.browser.privacy_sandbox.AdPersonalizationRemovedFragment;
@@ -436,9 +436,8 @@
                     .setCustomTabIntentHelper(
                             LaunchIntentDispatcher::createCustomTabActivityIntent);
         }
-        if (fragment instanceof PrivacySettings) {
-            ((PrivacySettings) fragment).setBottomSheetController(mBottomSheetController);
-            ((PrivacySettings) fragment).setDialogContainer(findViewById(R.id.dialog_container));
+        if (fragment instanceof PrivacyGuideFragment) {
+            ((PrivacyGuideFragment) fragment).setBottomSheetController(mBottomSheetController);
         }
         if (fragment instanceof AccessibilitySettings) {
             ((AccessibilitySettings) fragment)
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/IntentHandlerUnitTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/IntentHandlerUnitTest.java
index bf909bc..619589d 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/IntentHandlerUnitTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/IntentHandlerUnitTest.java
@@ -578,6 +578,45 @@
         assertTrue(mIntentHandler.shouldIgnoreIntent(intent, /*startedActivity=*/true));
     }
 
+    /**
+     * Test that IntentHandler#shouldIgnoreIntent() returns true for Incognito non-Custom Tab
+     * Intents.
+     */
+    @Test
+    @SmallTest
+    @Feature({"Android-AppBase"})
+    public void testShouldIgnoreIncognitoIntent() {
+        Intent intent = new Intent(GOOGLE_URL);
+        intent.putExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, true);
+        assertTrue(mIntentHandler.shouldIgnoreIntent(intent, /*startedActivity=*/true));
+    }
+
+    /**
+     * Test that IntentHandler#shouldIgnoreIntent() returns false for Incognito non-Custom Tab
+     * Intents if they come from Chrome.
+     */
+    @Test
+    @SmallTest
+    @Feature({"Android-AppBase"})
+    public void testShouldIgnoreIncognitoIntent_trusted() {
+        Context context = InstrumentationRegistry.getTargetContext();
+        Intent intent = IntentHandler.createTrustedOpenNewTabIntent(context, true);
+        assertFalse(mIntentHandler.shouldIgnoreIntent(intent, /*startedActivity=*/true));
+    }
+
+    /**
+     * Test that IntentHandler#shouldIgnoreIntent() returns false for Incognito Custom Tab Intents.
+     */
+    @Test
+    @SmallTest
+    @Feature({"Android-AppBase"})
+    public void testShouldIgnoreIncognitoIntent_customTab() {
+        Intent intent = new Intent(GOOGLE_URL);
+        intent.putExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, true);
+        assertFalse(mIntentHandler.shouldIgnoreIntent(
+                intent, /*startedActivity=*/true, /*isCustomTab=*/true));
+    }
+
     @Test
     @SmallTest
     public void testIgnoreUnauthenticatedBringToFront() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
index 1e98575..8b23dd9 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
@@ -14,6 +14,9 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
 
 import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE;
 import static org.chromium.chrome.browser.customtabs.CustomTabsTestUtils.createTestBitmap;
@@ -65,6 +68,7 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mockito;
 
 import org.chromium.base.ActivityState;
 import org.chromium.base.ApplicationStatus;
@@ -91,6 +95,7 @@
 import org.chromium.chrome.browser.ChromeApplicationImpl;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.IntentHandler;
+import org.chromium.chrome.browser.LaunchIntentDispatcher;
 import org.chromium.chrome.browser.TabsOpenedFromExternalAppTest;
 import org.chromium.chrome.browser.WarmupManager;
 import org.chromium.chrome.browser.browserservices.SessionDataHolder;
@@ -2063,4 +2068,40 @@
                 umaRecorded ? 1 : 0,
                 RecordHistogram.getHistogramTotalCountForTesting(histogramName));
     }
+
+    @Test
+    @SmallTest
+    public void doesNotLaunchJavaScriptUrls_dispatchToCustomTabActivity() {
+        Context context = InstrumentationRegistry.getTargetContext();
+        String javaScriptUrl = "javascript: alert('Hello');";
+
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            Intent intent =
+                    CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, javaScriptUrl);
+
+            Activity activity = Mockito.mock(Activity.class);
+            @LaunchIntentDispatcher.Action
+            int result = LaunchIntentDispatcher.dispatchToCustomTabActivity(activity, intent);
+            assertEquals(LaunchIntentDispatcher.Action.CONTINUE, result);
+            verify(activity, never()).startActivity(any(), any());
+        });
+    }
+
+    @Test
+    @SmallTest
+    public void doesNotLaunchJavaScriptUrls_dispatch() {
+        Context context = InstrumentationRegistry.getTargetContext();
+        String javaScriptUrl = "javascript: alert('Hello');";
+
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            Intent intent =
+                    CustomTabsIntentTestUtils.createMinimalCustomTabIntent(context, javaScriptUrl);
+
+            Activity activity = Mockito.mock(Activity.class);
+            @LaunchIntentDispatcher.Action
+            int result = LaunchIntentDispatcher.dispatch(activity, intent);
+            assertEquals(LaunchIntentDispatcher.Action.FINISH_ACTIVITY, result);
+            verify(activity, never()).startActivity(any(), any());
+        });
+    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoAboutThisSiteTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoAboutThisSiteTest.java
index f4687811..921459c 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoAboutThisSiteTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoAboutThisSiteTest.java
@@ -168,14 +168,14 @@
         };
     }
 
-    private void mockResponse(byte[] bytes) {
-        doReturn(bytes)
+    private void mockResponse(SiteInfo.Builder builder) {
+        doReturn(builder != null ? builder.build().toByteArray() : null)
                 .when(mMockAboutThisSiteJni)
                 .getSiteInfo(
                         any(BrowserContextHandle.class), any(GURL.class), any(WebContents.class));
     }
 
-    private byte[] createDescription() {
+    private SiteInfo.Builder createDescription() {
         String url = mTestServerRule.getServer().getURL(sSimpleHtml);
         String moreAboutUrl = mTestServerRule.getServer().getURL(sAboutHtml);
         SiteDescription.Builder description =
@@ -183,11 +183,7 @@
                         .setDescription("Some description about example.com for testing purposes")
                         .setSource(Hyperlink.newBuilder().setUrl(url).setLabel("Example Source"));
         MoreAbout.Builder moreAbout = MoreAbout.newBuilder().setUrl(moreAboutUrl);
-        return SiteInfo.newBuilder()
-                .setDescription(description)
-                .setMoreAbout(moreAbout)
-                .build()
-                .toByteArray();
+        return SiteInfo.newBuilder().setDescription(description).setMoreAbout(moreAbout);
     }
 
     @Test
@@ -221,6 +217,15 @@
 
     @Test
     @MediumTest
+    public void testAboutThisSiteRowWithoutDescription() throws TimeoutException {
+        mockResponse(createDescription().clearDescription());
+        openPageInfo();
+        onView(withId(PageInfoAboutThisSiteController.ROW_ID)).check(matches(isDisplayed()));
+        dismissPageInfo();
+    }
+
+    @Test
+    @MediumTest
     @Feature({"RenderTest"})
     public void testAboutThisSiteRowRendering() {
         mockResponse(createDescription());
@@ -308,12 +313,27 @@
     testAboutThisSiteOpensEphemeralTab() throws Exception {
         mockResponse(createDescription());
         openPageInfo();
+
         onView(withId(PageInfoAboutThisSiteController.ROW_ID)).perform(click());
         String moreAboutUrl = mTestServerRule.getServer().getURL(sAboutHtml);
         verify(mMockEphemeralTabCoordinator)
                 .requestOpenSheetWithFullPageUrl(/*url=*/new GURL(moreAboutUrl + "?ilrm=minimal"),
                         /*fullPageUrl=*/new GURL(moreAboutUrl), /*title=*/"About this page",
                         /*isIncognito=*/false);
+        verify(mMockAboutThisSiteJni).onAboutThisSiteRowClicked(true);
+    }
+
+    @Test
+    @MediumTest
+    @Features.EnableFeatures({ChromeFeatureList.PAGE_INFO_ABOUT_THIS_SITE_EN,
+            ChromeFeatureList.PAGE_INFO_ABOUT_THIS_SITE_NON_EN,
+            ChromeFeatureList.PAGE_INFO_ABOUT_THIS_SITE_MORE_INFO})
+    public void
+    testAboutThisSiteWithoutDescription() throws Exception {
+        mockResponse(createDescription().clearDescription());
+        openPageInfo();
+        onView(withId(PageInfoAboutThisSiteController.ROW_ID)).perform(click());
+        verify(mMockAboutThisSiteJni).onAboutThisSiteRowClicked(false);
     }
 
     @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java
index ad2d2122..8bbc9fa2 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java
@@ -108,6 +108,7 @@
  */
 @RunWith(ChromeJUnit4ClassRunner.class)
 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, "show-autofill-signatures"})
+@DisableFeatures(ChromeFeatureList.TANGIBLE_SYNC)
 public class MainSettingsFragmentTest {
     private static final String SEARCH_ENGINE_SHORT_NAME = "Google";
 
@@ -328,7 +329,6 @@
 
     @Test
     @SmallTest
-    @DisableFeatures(ChromeFeatureList.TANGIBLE_SYNC)
     public void testSyncRowLaunchesSignInFlowForSignedInAccounts() {
         CoreAccountInfo accountInfo = mSyncTestRule.setUpAccountAndSignInForTesting();
         launchSettingsActivity();
@@ -346,19 +346,16 @@
     public void testSyncRowLaunchesTangibleSignInFlowForSignedInAccounts() {
         CoreAccountInfo accountInfo = mSyncTestRule.setUpAccountAndSignInForTesting();
         launchSettingsActivity();
+
         onView(withText(R.string.sync_category_title)).perform(click());
+
         onView(withText(R.string.signin_account_picker_dialog_title))
                 .inRoot(isDialog())
                 .check(matches(isDisplayed()));
+        onView(withText(accountInfo.getEmail())).inRoot(isDialog()).check(matches(isDisplayed()));
         onView(withText(R.string.signin_add_account_to_device))
                 .inRoot(isDialog())
                 .check(matches(isDisplayed()));
-
-        onView(withText(accountInfo.getEmail())).inRoot(isDialog()).perform(click());
-
-        verify(mMockSyncConsentActivityLauncher)
-                .launchActivityForPromoDefaultFlow(any(Activity.class),
-                        eq(SigninAccessPoint.SETTINGS_SYNC_OFF_ROW), eq(accountInfo.getEmail()));
     }
 
     @Test
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index c5ee49c8..27e4654 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -12547,8 +12547,8 @@
       <message name="IDS_WEBAUTHN_CABLEV2_2ND_FACTOR_DESCRIPTION" desc="The contents of a dialog shown when the user tries to sign-in using a phone as a security key, or tries to register their phone as a security key for a future sign-in. A security key is traditionally a small USB device that is touched to confirm a sign-in (e.g. a gNubby) and, in this context, the phone is replacing the need for a separate device. The placeholder for the notification title will be replaced with the string that will appear in the notification on the phone. These messages are 4300134428943426639 and 581442427601260656.">
         <ph name="WEBSITE"><ex>accounts.google.com</ex>$1</ph> sent a notification to your phone. To confirm it's you, tap the “<ph name="NOTIFICATIONTITLE"><ex>Verify with this phone</ex>$2</ph>” notification and follow the steps.
       </message>
-      <message name="IDS_WEBAUTHN_CABLEV2_ADD_PHONE" desc="The label on a button-like element in a list of options. Clicking this causes Chrome to show a QR code that the user can scan with their phone to use that phone for signing into a website. Here 'phone' is used as a short hand for smartphone. Currently this ability is specific to Android phones.">
-        Add a new Android phone
+      <message name="IDS_WEBAUTHN_CABLEV2_ADD_PHONE" desc="The label on a button-like element in a list of options. Clicking this causes Chrome to show a QR code that the user can scan with their phone to use that phone for signing into a website. Here 'phone' is used as a short hand for smartphone.">
+        Use phone with a QR code
       </message>
 
       <message name="IDS_WEBAUTHN_CABLE_ACTIVATE_DESCRIPTION_SHORT" desc="Second line of text in an item letting the user know that they can use their phone as a security key. The user needs to check their phone and respond to a notification that will ask them to press a button on the phone's screen to confirm that they're logging in.">
diff --git a/chrome/app/generated_resources_grd/IDS_WEBAUTHN_CABLEV2_ADD_PHONE.png.sha1 b/chrome/app/generated_resources_grd/IDS_WEBAUTHN_CABLEV2_ADD_PHONE.png.sha1
index d7d3d8b..8a1d283 100644
--- a/chrome/app/generated_resources_grd/IDS_WEBAUTHN_CABLEV2_ADD_PHONE.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_WEBAUTHN_CABLEV2_ADD_PHONE.png.sha1
@@ -1 +1 @@
-8122b2c689bc290777f795143e2142cce10f58af
\ No newline at end of file
+ab81de45cc01f427997b8991b6c3cb26520b2622
\ No newline at end of file
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index 63676e70..caeac96 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -271,6 +271,18 @@
   </message>
 
   <!-- Autofill Page -->
+  <message name="IDS_PASSWORDS_PAGE_AUTHENTICATION_PROMPT_BIOMETRIC_SUFFIX" desc="Shown after 'Google Chrome is trying to ' (or in some languages, 'Google Chrome wants to ') in a dialog message. Text for the dialog box that prompts the user for the biometric authentication before revealing plaintext passwords on the password page.">
+    show passwords
+  </message>
+  <message name="IDS_PASSWORDS_PAGE_COPY_AUTHENTICATION_PROMPT_BIOMETRIC_SUFFIX" desc="Shown after 'Google Chrome is trying to ' (or in some languages, 'Google Chrome wants to ') in a dialog message. Text for the dialog box that prompts the user for the biometric authentication before copying plaintext passwords into the clipboard.">
+    copy passwords
+  </message>
+  <message name="IDS_PASSWORDS_PAGE_EDIT_AUTHENTICATION_PROMPT_BIOMETRIC_SUFFIX" desc="Shown after 'Google Chrome is trying to ' (or in some languages, 'Google Chrome wants to ') in a dialog message. Text for the dialog box that prompts the user for the biometric authentication before editing plaintext passwords on the password page.">
+    edit passwords
+  </message>
+  <message name="IDS_PASSWORDS_PAGE_EXPORT_AUTHENTICATION_PROMPT_BIOMETRIC_SUFFIX" desc="Shown after 'Google Chrome is trying to ' (or in some languages, 'Google Chrome wants to ') in a dialog message. Text for the dialog box that prompts the user for the biometric authentication before exporting passwords to a file.">
+    export passwords
+  </message>
   <message name="IDS_SETTINGS_AUTOFILL" desc="Name of the settings page which allows managing passwords, payment methods and addresses settings.">
     Autofill
   </message>
diff --git a/chrome/app/settings_strings_grdp/IDS_PASSWORDS_PAGE_AUTHENTICATION_PROMPT_BIOMETRIC_SUFFIX.png.sha1 b/chrome/app/settings_strings_grdp/IDS_PASSWORDS_PAGE_AUTHENTICATION_PROMPT_BIOMETRIC_SUFFIX.png.sha1
new file mode 100644
index 0000000..135c273
--- /dev/null
+++ b/chrome/app/settings_strings_grdp/IDS_PASSWORDS_PAGE_AUTHENTICATION_PROMPT_BIOMETRIC_SUFFIX.png.sha1
@@ -0,0 +1 @@
+7c26fb8b1749c374908b8c4c277f3dac4f4d9a86
\ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_PASSWORDS_PAGE_COPY_AUTHENTICATION_PROMPT_BIOMETRIC_SUFFIX.png.sha1 b/chrome/app/settings_strings_grdp/IDS_PASSWORDS_PAGE_COPY_AUTHENTICATION_PROMPT_BIOMETRIC_SUFFIX.png.sha1
new file mode 100644
index 0000000..4a8e344
--- /dev/null
+++ b/chrome/app/settings_strings_grdp/IDS_PASSWORDS_PAGE_COPY_AUTHENTICATION_PROMPT_BIOMETRIC_SUFFIX.png.sha1
@@ -0,0 +1 @@
+cd6a253cc5f708d6e4e2de8431df095cbef1022d
\ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_PASSWORDS_PAGE_EDIT_AUTHENTICATION_PROMPT_BIOMETRIC_SUFFIX.png.sha1 b/chrome/app/settings_strings_grdp/IDS_PASSWORDS_PAGE_EDIT_AUTHENTICATION_PROMPT_BIOMETRIC_SUFFIX.png.sha1
new file mode 100644
index 0000000..ef0e0e0
--- /dev/null
+++ b/chrome/app/settings_strings_grdp/IDS_PASSWORDS_PAGE_EDIT_AUTHENTICATION_PROMPT_BIOMETRIC_SUFFIX.png.sha1
@@ -0,0 +1 @@
+3136e367f179d38a5ab339634d0b71e28d6c3686
\ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_PASSWORDS_PAGE_EXPORT_AUTHENTICATION_PROMPT_BIOMETRIC_SUFFIX.png.sha1 b/chrome/app/settings_strings_grdp/IDS_PASSWORDS_PAGE_EXPORT_AUTHENTICATION_PROMPT_BIOMETRIC_SUFFIX.png.sha1
new file mode 100644
index 0000000..9ba3b83
--- /dev/null
+++ b/chrome/app/settings_strings_grdp/IDS_PASSWORDS_PAGE_EXPORT_AUTHENTICATION_PROMPT_BIOMETRIC_SUFFIX.png.sha1
@@ -0,0 +1 @@
+8b5dac306bec415d280cfee09f4e6021a039e63a
\ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 9110fcf..d573494b 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -3006,6 +3006,9 @@
       "enterprise/reporting/reporting_delegate_factory_android.h",
       "enterprise/util/android_enterprise_info.cc",
       "enterprise/util/android_enterprise_info.h",
+      "fast_checkout/fast_checkout_capabilities_fetcher.h",
+      "fast_checkout/fast_checkout_capabilities_fetcher_impl.cc",
+      "fast_checkout/fast_checkout_capabilities_fetcher_impl.h",
       "fast_checkout/fast_checkout_client.cc",
       "fast_checkout/fast_checkout_client.h",
       "fast_checkout/fast_checkout_client_impl.cc",
@@ -5342,6 +5345,8 @@
       "chromeos/app_mode/app_session_browser_window_handler.h",
       "chromeos/app_mode/app_session_metrics_service.cc",
       "chromeos/app_mode/app_session_metrics_service.h",
+      "chromeos/app_mode/app_session_policies.cc",
+      "chromeos/app_mode/app_session_policies.h",
       "chromeos/app_mode/chrome_kiosk_app_installer.cc",
       "chromeos/app_mode/chrome_kiosk_app_installer.h",
       "chromeos/app_mode/chrome_kiosk_app_launcher.cc",
@@ -7561,6 +7566,8 @@
       "supervised_user/kids_chrome_management/kids_chrome_management_client_factory.h",
       "supervised_user/kids_chrome_management/kids_external_fetcher.cc",
       "supervised_user/kids_chrome_management/kids_external_fetcher.h",
+      "supervised_user/kids_chrome_management/kids_management_service.cc",
+      "supervised_user/kids_chrome_management/kids_management_service.h",
       "supervised_user/kids_management_url_checker_client.cc",
       "supervised_user/kids_management_url_checker_client.h",
       "supervised_user/parental_control_metrics.cc",
diff --git a/chrome/browser/accessibility/ax_screen_ai_annotator.cc b/chrome/browser/accessibility/ax_screen_ai_annotator.cc
index bc458ef..5dbe39ab 100644
--- a/chrome/browser/accessibility/ax_screen_ai_annotator.cc
+++ b/chrome/browser/accessibility/ax_screen_ai_annotator.cc
@@ -15,17 +15,23 @@
 
 namespace screen_ai {
 
-AXScreenAIAnnotator::AXScreenAIAnnotator(Browser* browser) : browser_(browser) {
-  mojo::PendingReceiver<screen_ai::mojom::ScreenAIAnnotator>
-      screen_ai_receiver = screen_ai_annotator_.BindNewPipeAndPassReceiver();
-  ScreenAIServiceRouterFactory::GetForBrowserContext(
-      static_cast<content::BrowserContext*>(browser->profile()))
-      ->BindScreenAIAnnotator(std::move(screen_ai_receiver));
-}
+AXScreenAIAnnotator::AXScreenAIAnnotator(Browser* browser)
+    : browser_(browser) {}
 
 AXScreenAIAnnotator::~AXScreenAIAnnotator() = default;
 
+void AXScreenAIAnnotator::BindToScreenAIService() {
+  mojo::PendingReceiver<screen_ai::mojom::ScreenAIAnnotator>
+      screen_ai_receiver = screen_ai_annotator_.BindNewPipeAndPassReceiver();
+  ScreenAIServiceRouterFactory::GetForBrowserContext(
+      static_cast<content::BrowserContext*>(browser_->profile()))
+      ->BindScreenAIAnnotator(std::move(screen_ai_receiver));
+}
+
 void AXScreenAIAnnotator::Run() {
+  if (!screen_ai_annotator_.is_bound())
+    BindToScreenAIService();
+
   // Request screenshot from content area of the main frame.
   content::WebContents* web_contents =
       browser_->tab_strip_model()->GetActiveWebContents();
@@ -45,8 +51,8 @@
     return;
   }
 
-  AXScreenAIAnnotator::OnScreenshotReceived(
-      web_contents->GetPrimaryMainFrame()->GetAXTreeID(), std::move(snapshot));
+  OnScreenshotReceived(web_contents->GetPrimaryMainFrame()->GetAXTreeID(),
+                       std::move(snapshot));
 #else
   ui::GrabViewSnapshotAsync(
       native_view, gfx::Rect(web_contents->GetSize()),
@@ -58,6 +64,7 @@
 
 void AXScreenAIAnnotator::OnScreenshotReceived(const ui::AXTreeID& ax_tree_id,
                                                gfx::Image snapshot) {
+  DCHECK(screen_ai_annotator_.is_bound());
   screen_ai_annotator_->Annotate(
       snapshot.AsBitmap(),
       base::BindOnce(&AXScreenAIAnnotator::OnAnnotationReceived,
diff --git a/chrome/browser/accessibility/ax_screen_ai_annotator.h b/chrome/browser/accessibility/ax_screen_ai_annotator.h
index ef179ddd..4f9196f 100644
--- a/chrome/browser/accessibility/ax_screen_ai_annotator.h
+++ b/chrome/browser/accessibility/ax_screen_ai_annotator.h
@@ -26,6 +26,9 @@
   AXScreenAIAnnotator(const AXScreenAIAnnotator&) = delete;
   AXScreenAIAnnotator& operator=(const AXScreenAIAnnotator&) = delete;
 
+  // Binds |screen_ai_annotator_| to the Screen AI service.
+  virtual void BindToScreenAIService();
+
   // Takes a screenshot and sends it to |OnScreenshotReceived| through an async
   // call.
   void Run();
diff --git a/chrome/browser/accessibility/screen_ai_service_browsertest.cc b/chrome/browser/accessibility/screen_ai_service_browsertest.cc
index f5e840575..cabdee7 100644
--- a/chrome/browser/accessibility/screen_ai_service_browsertest.cc
+++ b/chrome/browser/accessibility/screen_ai_service_browsertest.cc
@@ -18,6 +18,12 @@
  public:
   explicit MockAXScreenAIAnnotator(Browser* browser)
       : AXScreenAIAnnotator(browser) {}
+
+  // TODO(https://1278249): Consider making Screen AI component available for
+  // tests. The test should refrain from trying to bind to it while it is not
+  // available.
+  MOCK_METHOD(void, BindToScreenAIService, (), (override));
+
   MOCK_METHOD(void,
               OnScreenshotReceived,
               (const ui::AXTreeID& ax_tree_id, gfx::Image snapshot),
@@ -28,20 +34,14 @@
 
 using ScreenAIServiceTest = InProcessBrowserTest;
 
-// https://crbug.com/1348280: Creating AXScreenAIAnnotator triggers the sandbox
-// on Mac11 which is not implemented yet.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_ScreenshotTest DISABLED_ScreenshotTest
-#else
-#define MAYBE_ScreenshotTest ScreenshotTest
-#endif
-IN_PROC_BROWSER_TEST_F(ScreenAIServiceTest, MAYBE_ScreenshotTest) {
+IN_PROC_BROWSER_TEST_F(ScreenAIServiceTest, ScreenshotTest) {
   MockAXScreenAIAnnotator* annotator = new MockAXScreenAIAnnotator(browser());
   browser()->SetScreenAIAnnotatorForTesting(
       std::unique_ptr<AXScreenAIAnnotator>(annotator));
 
   base::RunLoop run_loop;
 
+  EXPECT_CALL(*annotator, BindToScreenAIService);
   EXPECT_CALL(*annotator, OnScreenshotReceived)
       .WillOnce(
           [&run_loop](const ui::AXTreeID& ax_tree_id, gfx::Image snapshot) {
@@ -54,8 +54,9 @@
   browser()->RunScreenAIAnnotator();
   run_loop.Run();
 
-  // TODO(https://crbug.com/1278249): Expect OnAnnotationReceived once library
-  // binary is available for test.
+  // TODO(https://crbug.com/1278249): Add a test that mocks
+  // |OnScreenshotReceived| and returns the expected proto, and observe its
+  // application on the accessibility tree(s).
 }
 
 }  // namespace screen_ai
diff --git a/chrome/browser/android/vr/gvr_graphics_delegate.cc b/chrome/browser/android/vr/gvr_graphics_delegate.cc
index 5b128d8..0f9fd4b 100644
--- a/chrome/browser/android/vr/gvr_graphics_delegate.cc
+++ b/chrome/browser/android/vr/gvr_graphics_delegate.cc
@@ -18,8 +18,11 @@
 #include "chrome/browser/vr/vr_geometry_util.h"
 #include "device/vr/android/web_xr_presentation_state.h"
 #include "device/vr/vr_gl_util.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkEncodedImageFormat.h"
 #include "third_party/skia/include/core/SkImageEncoder.h"
 #include "third_party/skia/include/core/SkPixmap.h"
+#include "third_party/skia/include/core/SkStream.h"
 #include "ui/gfx/geometry/angle_conversions.h"
 #include "ui/gl/android/scoped_java_surface.h"
 #include "ui/gl/android/surface_texture.h"
diff --git a/chrome/browser/ash/crosapi/crosapi_ash.cc b/chrome/browser/ash/crosapi/crosapi_ash.cc
index 5f31f30..b6823b2 100644
--- a/chrome/browser/ash/crosapi/crosapi_ash.cc
+++ b/chrome/browser/ash/crosapi/crosapi_ash.cc
@@ -98,6 +98,7 @@
 #include "chrome/browser/ash/remote_apps/remote_apps_manager_factory.h"
 #include "chrome/browser/ash/sync/sync_service_ash.h"
 #include "chrome/browser/ash/sync/sync_service_factory_ash.h"
+#include "chrome/browser/ash/telemetry_extension/diagnostics_service_ash.h"
 #include "chrome/browser/ash/telemetry_extension/probe_service_ash.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part.h"
@@ -184,6 +185,7 @@
       device_oauth2_token_service_ash_(
           std::make_unique<DeviceOAuth2TokenServiceAsh>()),
       device_settings_ash_(std::make_unique<DeviceSettingsAsh>()),
+      diagnostics_service_ash_(std::make_unique<ash::DiagnosticsServiceAsh>()),
       digital_goods_factory_ash_(
           std::make_unique<apps::DigitalGoodsFactoryAsh>()),
       dlp_ash_(std::make_unique<DlpAsh>()),
@@ -648,6 +650,11 @@
   device_settings_ash_->BindReceiver(std::move(receiver));
 }
 
+void CrosapiAsh::BindDiagnosticsService(
+    mojo::PendingReceiver<mojom::DiagnosticsService> receiver) {
+  diagnostics_service_ash_->BindReceiver(std::move(receiver));
+}
+
 void CrosapiAsh::BindDigitalGoodsFactory(
     mojo::PendingReceiver<mojom::DigitalGoodsFactory> receiver) {
   digital_goods_factory_ash_->BindReceiver(std::move(receiver));
diff --git a/chrome/browser/ash/crosapi/crosapi_ash.h b/chrome/browser/ash/crosapi/crosapi_ash.h
index 1068806..816e0e1 100644
--- a/chrome/browser/ash/crosapi/crosapi_ash.h
+++ b/chrome/browser/ash/crosapi/crosapi_ash.h
@@ -27,6 +27,7 @@
 }
 
 namespace ash {
+class DiagnosticsServiceAsh;
 class ProbeServiceAsh;
 }  // namespace ash
 
@@ -173,6 +174,8 @@
       mojo::PendingReceiver<mojom::DeviceOAuth2TokenService> receiver) override;
   void BindDeviceSettingsService(
       mojo::PendingReceiver<mojom::DeviceSettingsService> receiver) override;
+  void BindDiagnosticsService(
+      mojo::PendingReceiver<mojom::DiagnosticsService> receiver) override;
   void BindDigitalGoodsFactory(
       mojo::PendingReceiver<mojom::DigitalGoodsFactory> receiver) override;
   void BindDlp(mojo::PendingReceiver<mojom::Dlp> receiver) override;
@@ -456,6 +459,7 @@
   std::unique_ptr<DeviceAttributesAsh> device_attributes_ash_;
   std::unique_ptr<DeviceOAuth2TokenServiceAsh> device_oauth2_token_service_ash_;
   std::unique_ptr<DeviceSettingsAsh> device_settings_ash_;
+  std::unique_ptr<ash::DiagnosticsServiceAsh> diagnostics_service_ash_;
   std::unique_ptr<apps::DigitalGoodsFactoryAsh> digital_goods_factory_ash_;
   std::unique_ptr<DlpAsh> dlp_ash_;
   std::unique_ptr<DocumentScanAsh> document_scan_ash_;
diff --git a/chrome/browser/ash/crosapi/crosapi_util.cc b/chrome/browser/ash/crosapi/crosapi_util.cc
index 0d39fe8c..98c2be11d 100644
--- a/chrome/browser/ash/crosapi/crosapi_util.cc
+++ b/chrome/browser/ash/crosapi/crosapi_util.cc
@@ -59,6 +59,7 @@
 #include "chromeos/crosapi/mojom/device_attributes.mojom.h"
 #include "chromeos/crosapi/mojom/device_oauth2_token_service.mojom.h"
 #include "chromeos/crosapi/mojom/device_settings_service.mojom.h"
+#include "chromeos/crosapi/mojom/diagnostics_service.mojom.h"
 #include "chromeos/crosapi/mojom/digital_goods.mojom.h"
 #include "chromeos/crosapi/mojom/dlp.mojom.h"
 #include "chromeos/crosapi/mojom/document_scan.mojom.h"
@@ -242,7 +243,7 @@
   return {T::Uuid_, T::Version_};
 }
 
-static_assert(crosapi::mojom::Crosapi::Version_ == 94,
+static_assert(crosapi::mojom::Crosapi::Version_ == 95,
               "If you add a new crosapi, please add it to "
               "kInterfaceVersionEntries below.");
 
@@ -274,6 +275,7 @@
     MakeInterfaceVersionEntry<crosapi::mojom::DeviceAttributes>(),
     MakeInterfaceVersionEntry<crosapi::mojom::DeviceOAuth2TokenService>(),
     MakeInterfaceVersionEntry<crosapi::mojom::DeviceSettingsService>(),
+    MakeInterfaceVersionEntry<crosapi::mojom::DiagnosticsService>(),
     MakeInterfaceVersionEntry<crosapi::mojom::DigitalGoodsFactory>(),
     MakeInterfaceVersionEntry<crosapi::mojom::Dlp>(),
     MakeInterfaceVersionEntry<crosapi::mojom::DocumentScan>(),
diff --git a/chrome/browser/ash/customization/customization_document.cc b/chrome/browser/ash/customization/customization_document.cc
index c2aaf2a..452fd7ca 100644
--- a/chrome/browser/ash/customization/customization_document.cc
+++ b/chrome/browser/ash/customization/customization_document.cc
@@ -149,25 +149,26 @@
                             HISTOGRAM_LOAD_RESULT_MAX_VALUE);
 }
 
-std::string GetLocaleSpecificStringImpl(
-    const base::DictionaryValue* root,
-    const std::string& locale,
-    const std::string& dictionary_name,
-    const std::string& entry_name) {
-  const base::DictionaryValue* dictionary_content = NULL;
-  if (!root || !root->GetDictionary(dictionary_name, &dictionary_content))
+std::string GetLocaleSpecificStringImpl(const base::Value::Dict& root,
+                                        const std::string& locale,
+                                        const std::string& dictionary_name,
+                                        const std::string& entry_name) {
+  const base::Value::Dict* dictionary_content = root.FindDict(dictionary_name);
+  if (!dictionary_content)
     return std::string();
 
-  const base::DictionaryValue* locale_dictionary = NULL;
-  if (dictionary_content->GetDictionary(locale, &locale_dictionary)) {
-    const std::string* result = locale_dictionary->FindStringKey(entry_name);
+  const base::Value::Dict* locale_dictionary =
+      dictionary_content->FindDict(locale);
+  if (locale_dictionary) {
+    const std::string* result = locale_dictionary->FindString(entry_name);
     if (result)
       return *result;
   }
 
-  const base::DictionaryValue* default_dictionary = NULL;
-  if (dictionary_content->GetDictionary(kDefaultAttr, &default_dictionary)) {
-    const std::string* result = default_dictionary->FindStringKey(entry_name);
+  const base::Value::Dict* default_dictionary =
+      dictionary_content->FindDict(kDefaultAttr);
+  if (default_dictionary) {
+    const std::string* result = default_dictionary->FindString(entry_name);
     if (result)
       return *result;
   }
@@ -277,16 +278,16 @@
     NOTREACHED();
     return false;
   }
-  std::unique_ptr<base::Value> root =
-      base::Value::ToUniquePtrValue(std::move(*parsed_json));
 
-  root_ = base::DictionaryValue::From(std::move(root));
-  if (!root_) {
+  if (!parsed_json->is_dict()) {
     NOTREACHED();
     return false;
   }
 
-  const std::string* result = root_->FindStringKey(kVersionAttr);
+  root_ =
+      std::make_unique<base::Value::Dict>(std::move(parsed_json->GetDict()));
+
+  const std::string* result = root_->FindString(kVersionAttr);
   if (!result || *result != accepted_version_) {
     LOG(ERROR) << "Wrong customization manifest version";
     root_.reset();
@@ -300,8 +301,8 @@
     const std::string& locale,
     const std::string& dictionary_name,
     const std::string& entry_name) const {
-  return GetLocaleSpecificStringImpl(
-      root_.get(), locale, dictionary_name, entry_name);
+  return GetLocaleSpecificStringImpl(*root_, locale, dictionary_name,
+                                     entry_name);
 }
 
 // StartupCustomizationDocument implementation. --------------------------------
@@ -340,49 +341,49 @@
     chromeos::system::StatisticsProvider* statistics_provider) {
   if (IsReady()) {
     const std::string* initial_locale_ptr =
-        root_->FindStringKey(kInitialLocaleAttr);
+        root_->FindString(kInitialLocaleAttr);
     if (initial_locale_ptr)
       initial_locale_ = *initial_locale_ptr;
 
     const std::string* initial_timezone_ptr =
-        root_->FindStringKey(kInitialTimezoneAttr);
+        root_->FindString(kInitialTimezoneAttr);
     if (initial_timezone_ptr)
       initial_timezone_ = *initial_timezone_ptr;
 
     const std::string* keyboard_layout_ptr =
-        root_->FindStringKey(kKeyboardLayoutAttr);
+        root_->FindString(kKeyboardLayoutAttr);
     if (keyboard_layout_ptr)
       keyboard_layout_ = *keyboard_layout_ptr;
 
     std::string hwid;
     if (statistics_provider->GetMachineStatistic(
             chromeos::system::kHardwareClassKey, &hwid)) {
-      base::ListValue* hwid_list = NULL;
-      if (root_->GetList(kHwidMapAttr, &hwid_list)) {
-        for (const base::Value& hwid_value : hwid_list->GetListDeprecated()) {
-          const base::DictionaryValue* hwid_dictionary = nullptr;
+      base::Value::List* hwid_list = root_->FindList(kHwidMapAttr);
+      if (hwid_list) {
+        for (const base::Value& hwid_value : *hwid_list) {
+          const base::Value::Dict* hwid_dictionary = nullptr;
           if (hwid_value.is_dict())
-            hwid_dictionary = &base::Value::AsDictionaryValue(hwid_value);
+            hwid_dictionary = &hwid_value.GetDict();
 
           const std::string* hwid_mask =
-              hwid_dictionary ? hwid_dictionary->FindStringKey(kHwidMaskAttr)
+              hwid_dictionary ? hwid_dictionary->FindString(kHwidMaskAttr)
                               : nullptr;
           if (hwid_mask) {
             if (base::MatchPattern(hwid, *hwid_mask)) {
               // If HWID for this machine matches some mask, use HWID specific
               // settings.
               const std::string* initial_locale =
-                  hwid_dictionary->FindStringKey(kInitialLocaleAttr);
+                  hwid_dictionary->FindString(kInitialLocaleAttr);
               if (initial_locale)
                 initial_locale_ = *initial_locale;
 
               const std::string* initial_timezone =
-                  hwid_dictionary->FindStringKey(kInitialTimezoneAttr);
+                  hwid_dictionary->FindString(kInitialTimezoneAttr);
               if (initial_timezone)
                 initial_timezone_ = *initial_timezone;
 
               const std::string* keyboard_layout =
-                  hwid_dictionary->FindStringKey(kKeyboardLayoutAttr);
+                  hwid_dictionary->FindString(kKeyboardLayoutAttr);
               if (keyboard_layout)
                 keyboard_layout_ = *keyboard_layout;
             }
@@ -717,7 +718,7 @@
   if (!IsReady())
     return false;
 
-  const std::string* url = root_->FindStringKey(kDefaultWallpaperAttr);
+  const std::string* url = root_->FindString(kDefaultWallpaperAttr);
   if (!url)
     return false;
 
@@ -743,14 +744,13 @@
 
 std::unique_ptr<base::DictionaryValue>
 ServicesCustomizationDocument::GetDefaultAppsInProviderFormat(
-    const base::DictionaryValue& root) {
+    const base::Value::Dict& root) {
   std::unique_ptr<base::DictionaryValue> prefs(new base::DictionaryValue);
-  const base::ListValue* apps_list = NULL;
-  if (root.GetList(kDefaultAppsAttr, &apps_list)) {
-    for (size_t i = 0; i < apps_list->GetListDeprecated().size(); ++i) {
+  const base::Value::List* apps_list = root.FindList(kDefaultAppsAttr);
+  if (apps_list) {
+    for (const base::Value& app_entry_value : *apps_list) {
       std::string app_id;
       std::unique_ptr<base::DictionaryValue> entry;
-      const base::Value& app_entry_value = apps_list->GetListDeprecated()[i];
       if (app_entry_value.is_string()) {
         app_id = app_entry_value.GetString();
         entry = std::make_unique<base::DictionaryValue>();
@@ -785,7 +785,7 @@
 }
 
 void ServicesCustomizationDocument::UpdateCachedManifest(Profile* profile) {
-  profile->GetPrefs()->Set(kServicesCustomizationKey, *root_);
+  profile->GetPrefs()->SetDict(kServicesCustomizationKey, root_->Clone());
 }
 
 extensions::ExternalLoader* ServicesCustomizationDocument::CreateExternalLoader(
@@ -799,12 +799,12 @@
     loader->SetCurrentApps(GetDefaultAppsInProviderFormat(*root_));
     SetOemFolderName(profile, *root_);
   } else {
-    const base::DictionaryValue* root = &base::Value::AsDictionaryValue(
-        *profile->GetPrefs()->GetDictionary(kServicesCustomizationKey));
-    if (root && root->FindStringKey(kVersionAttr)) {
+    const base::Value::Dict& root =
+        profile->GetPrefs()->GetValueDict(kServicesCustomizationKey);
+    if (root.FindString(kVersionAttr)) {
       // If version exists, profile has cached version of customization.
-      loader->SetCurrentApps(GetDefaultAppsInProviderFormat(*root));
-      SetOemFolderName(profile, *root);
+      loader->SetCurrentApps(GetDefaultAppsInProviderFormat(root));
+      SetOemFolderName(profile, root);
     } else {
       // StartFetching will be called from ServicesCustomizationExternalLoader
       // when StartLoading is called. We can't initiate manifest fetch here
@@ -822,7 +822,7 @@
 
 void ServicesCustomizationDocument::SetOemFolderName(
     Profile* profile,
-    const base::DictionaryValue& root) {
+    const base::Value::Dict& root) {
   std::string locale = g_browser_process->GetApplicationLocale();
   std::string name = GetOemAppsFolderNameImpl(locale, root);
   if (name.empty())
@@ -841,9 +841,9 @@
 
 std::string ServicesCustomizationDocument::GetOemAppsFolderNameImpl(
     const std::string& locale,
-    const base::DictionaryValue& root) const {
-  return GetLocaleSpecificStringImpl(
-      &root, locale, kLocalizedContent, kDefaultAppsFolderName);
+    const base::Value::Dict& root) const {
+  return GetLocaleSpecificStringImpl(root, locale, kLocalizedContent,
+                                     kDefaultAppsFolderName);
 }
 
 // static
diff --git a/chrome/browser/ash/customization/customization_document.h b/chrome/browser/ash/customization/customization_document.h
index 37199d2..13f08964 100644
--- a/chrome/browser/ash/customization/customization_document.h
+++ b/chrome/browser/ash/customization/customization_document.h
@@ -77,7 +77,7 @@
                                       const std::string& dictionary_name,
                                       const std::string& entry_name) const;
 
-  std::unique_ptr<base::DictionaryValue> root_;
+  std::unique_ptr<base::Value::Dict> root_;
 
   // Value of the "version" attribute that is supported.
   // Otherwise config is not loaded.
@@ -251,7 +251,7 @@
 
   // Returns list of default apps in ExternalProvider format.
   static std::unique_ptr<base::DictionaryValue> GetDefaultAppsInProviderFormat(
-      const base::DictionaryValue& root);
+      const base::Value::Dict& root);
 
   // Update cached manifest for |profile|.
   void UpdateCachedManifest(Profile* profile);
@@ -260,12 +260,11 @@
   void OnCustomizationNotFound();
 
   // Set OEM apps folder name for AppListSyncableService for |profile|.
-  void SetOemFolderName(Profile* profile, const base::DictionaryValue& root);
+  void SetOemFolderName(Profile* profile, const base::Value::Dict& root);
 
   // Returns the name of the folder for OEM apps for given |locale|.
-  std::string GetOemAppsFolderNameImpl(
-      const std::string& locale,
-      const base::DictionaryValue& root) const;
+  std::string GetOemAppsFolderNameImpl(const std::string& locale,
+                                       const base::Value::Dict& root) const;
 
   // Start download of wallpaper image if needed.
   void StartOEMWallpaperDownload(const GURL& wallpaper_url,
diff --git a/chrome/browser/ash/file_manager/path_util.cc b/chrome/browser/ash/file_manager/path_util.cc
index 964f829..f94025a3 100644
--- a/chrome/browser/ash/file_manager/path_util.cc
+++ b/chrome/browser/ash/file_manager/path_util.cc
@@ -1082,6 +1082,7 @@
       break;
     case VOLUME_TYPE_ANDROID_FILES:
     case VOLUME_TYPE_CROSTINI:
+    case VOLUME_TYPE_GUEST_OS:
       result = base::FilePath(l10n_util::GetStringUTF8(
                                   IDS_FILE_BROWSER_MY_FILES_ROOT_LABEL))
                    .Append(volume->volume_label());
@@ -1091,7 +1092,6 @@
     case VOLUME_TYPE_MOUNTED_ARCHIVE_FILE:
     case VOLUME_TYPE_PROVIDED:
     case VOLUME_TYPE_DOCUMENTS_PROVIDER:
-    case VOLUME_TYPE_GUEST_OS:
     case VOLUME_TYPE_MTP:
     case VOLUME_TYPE_SMB:
       result = base::FilePath(volume->volume_label());
diff --git a/chrome/browser/ash/file_manager/path_util_unittest.cc b/chrome/browser/ash/file_manager/path_util_unittest.cc
index a9a0271b..674861c7 100644
--- a/chrome/browser/ash/file_manager/path_util_unittest.cc
+++ b/chrome/browser/ash/file_manager/path_util_unittest.cc
@@ -1259,6 +1259,10 @@
           "My files/Linux files/foo",
       },
       {
+          "/mount_path/guest_os/foo",
+          "My files/guest_os_label/foo",
+      },
+      {
           "/mount_path/provided/foo",
           "provided_label/foo",
       },
@@ -1280,10 +1284,6 @@
           "documents_provider_label",
       },
       {
-          "/mount_path/guest_os/foo",
-          "guest_os_label/foo",
-      },
-      {
           "/mount_path/mtp",
           "mtp_label",
       },
diff --git a/chrome/browser/ash/file_system_provider/registry.cc b/chrome/browser/ash/file_system_provider/registry.cc
index 069525c4..f2dea3d 100644
--- a/chrome/browser/ash/file_system_provider/registry.cc
+++ b/chrome/browser/ash/file_system_provider/registry.cc
@@ -129,12 +129,11 @@
   PrefService* const pref_service = profile_->GetPrefs();
   DCHECK(pref_service);
 
-  const base::Value* const file_systems =
-      pref_service->GetDictionary(prefs::kFileSystemProviderMounted);
-  DCHECK(file_systems);
+  const base::Value::Dict& file_systems =
+      pref_service->GetValueDict(prefs::kFileSystemProviderMounted);
 
-  const base::Value* file_systems_per_extension =
-      file_systems->FindDictKey(provider_id.ToString());
+  const base::Value::Dict* file_systems_per_extension =
+      file_systems.FindDict(provider_id.ToString());
   if (!file_systems_per_extension) {
     return base::WrapUnique(new RestoredFileSystems);  // Nothing to restore.
   }
@@ -142,25 +141,24 @@
   std::unique_ptr<RestoredFileSystems> restored_file_systems(
       new RestoredFileSystems);
 
-  for (const auto it : file_systems_per_extension->DictItems()) {
-    const base::Value* file_system =
-        file_systems_per_extension->FindDictKey(it.first);
-
-    if (!file_system) {
+  for (const auto it : *file_systems_per_extension) {
+    if (!it.second.is_dict()) {
       LOG(ERROR)
           << "Malformed provided file system information in preferences.";
       continue;
     }
 
+    const base::Value::Dict& file_system = it.second.GetDict();
+
     const std::string* file_system_id =
-        file_system->FindStringKey(kPrefKeyFileSystemId);
+        file_system.FindString(kPrefKeyFileSystemId);
     const std::string* display_name =
-        file_system->FindStringKey(kPrefKeyDisplayName);
-    absl::optional<bool> writable = file_system->FindBoolKey(kPrefKeyWritable);
+        file_system.FindString(kPrefKeyDisplayName);
+    absl::optional<bool> writable = file_system.FindBool(kPrefKeyWritable);
     absl::optional<bool> supports_notify_tag =
-        file_system->FindBoolKey(kPrefKeySupportsNotifyTag);
+        file_system.FindBool(kPrefKeySupportsNotifyTag);
     absl::optional<int> opened_files_limit =
-        file_system->FindIntKey(kPrefKeyOpenedFilesLimit);
+        file_system.FindInt(kPrefKeyOpenedFilesLimit);
 
     // TODO(mtomasz): Move opened files limit to the mandatory list above in
     // M42.
@@ -186,29 +184,29 @@
     restored_file_system.options = options;
 
     // Restore watchers. It's optional, since this field is new.
-    const base::Value* watchers = file_system->FindDictKey(kPrefKeyWatchers);
+    const base::Value::Dict* watchers = file_system.FindDict(kPrefKeyWatchers);
     if (watchers) {
-      for (const auto it : watchers->DictItems()) {
-        const base::Value* watcher = watchers->FindDictKey(it.first);
-        if (!watcher) {
+      for (const auto it : *watchers) {
+        if (!it.second.is_dict()) {
           LOG(ERROR) << "Malformed watcher information in preferences.";
           continue;
         }
 
+        const base::Value::Dict& watcher = it.second.GetDict();
+
         const std::string* entry_path =
-            watcher->FindStringKey(kPrefKeyWatcherEntryPath);
+            watcher.FindString(kPrefKeyWatcherEntryPath);
         absl::optional<bool> recursive =
-            watcher->FindBoolKey(kPrefKeyWatcherRecursive);
+            watcher.FindBool(kPrefKeyWatcherRecursive);
         const std::string* last_tag =
-            watcher->FindStringKey(kPrefKeyWatcherLastTag);
-        const base::Value* persistent_origins =
-            watcher->FindListKey(kPrefKeyWatcherPersistentOrigins);
+            watcher.FindString(kPrefKeyWatcherLastTag);
+        const base::Value::List* persistent_origins =
+            watcher.FindList(kPrefKeyWatcherPersistentOrigins);
 
         if (!entry_path || !recursive || !last_tag || !persistent_origins ||
             it.first != *entry_path || entry_path->empty() ||
             (!options.supports_notify_tag &&
-             (!last_tag->empty() ||
-              persistent_origins->GetListDeprecated().size()))) {
+             (!last_tag->empty() || persistent_origins->size()))) {
           LOG(ERROR) << "Malformed watcher information in preferences.";
           continue;
         }
@@ -218,8 +216,7 @@
             base::FilePath::FromUTF8Unsafe(*entry_path);
         restored_watcher.recursive = recursive.value();
         restored_watcher.last_tag = *last_tag;
-        for (const auto& persistent_origin :
-             persistent_origins->GetListDeprecated()) {
+        for (const auto& persistent_origin : *persistent_origins) {
           if (!persistent_origin.is_string()) {
             LOG(ERROR) << "Malformed subscriber information in preferences.";
             continue;
diff --git a/chrome/browser/ash/input_method/autocorrect_manager.cc b/chrome/browser/ash/input_method/autocorrect_manager.cc
index 28fc368..a2ef537 100644
--- a/chrome/browser/ash/input_method/autocorrect_manager.cc
+++ b/chrome/browser/ash/input_method/autocorrect_manager.cc
@@ -119,15 +119,7 @@
     return false;
   }
   if (event.code() == ui::DomCode::ARROW_UP && window_visible_) {
-    std::string error;
-    auto button = ui::ime::AssistiveWindowButton();
-    button.id = ui::ime::ButtonId::kUndo;
-    button.window_type = ui::ime::AssistiveWindowType::kUndoWindow;
-    button.announce_string = l10n_util::GetStringFUTF16(
-        IDS_SUGGESTION_AUTOCORRECT_UNDO_BUTTON, original_text_);
-    suggestion_handler_->SetButtonHighlighted(context_id_, button, true,
-                                              &error);
-    button_highlighted_ = true;
+    HighlightUndoButton();
     return true;
   }
   if (event.code() == ui::DomCode::ENTER && window_visible_ &&
@@ -175,31 +167,10 @@
   // 3) Ensure there is no selection (selection UI clashes with autocorrect UI).
   if (!range.is_empty() && cursor_pos_unsigned >= range.start() &&
       cursor_pos_unsigned <= range.end() && cursor_pos == anchor_pos) {
-    if (!window_visible_) {
-      const std::u16string autocorrected_text =
-          text.substr(range.start(), range.length());
-      AssistiveWindowProperties properties;
-      properties.type = ui::ime::AssistiveWindowType::kUndoWindow;
-      properties.visible = true;
-      properties.announce_string = l10n_util::GetStringFUTF16(
-          IDS_SUGGESTION_AUTOCORRECT_UNDO_WINDOW_SHOWN, original_text_,
-          autocorrected_text);
-      window_visible_ = true;
-      button_highlighted_ = false;
-      suggestion_handler_->SetAssistiveWindowProperties(context_id_, properties,
-                                                        &error);
-      LogAssistiveAutocorrectAction(AutocorrectActions::kWindowShown);
-      RecordAssistiveCoverage(AssistiveType::kAutocorrectWindowShown);
-    }
+    ShowUndoWindow(range, text);
     key_presses_until_underline_hide_ = kKeysUntilUnderlineHides;
-  } else if (window_visible_) {
-    AssistiveWindowProperties properties;
-    properties.type = ui::ime::AssistiveWindowType::kUndoWindow;
-    properties.visible = false;
-    window_visible_ = false;
-    button_highlighted_ = false;
-    suggestion_handler_->SetAssistiveWindowProperties(context_id_, properties,
-                                                      &error);
+  } else {
+    HideUndoWindow();
   }
 }
 
@@ -220,15 +191,7 @@
 }
 
 void AutocorrectManager::UndoAutocorrect() {
-  // TODO(crbug/1111135): error handling and metrics
-  std::string error;
-  AssistiveWindowProperties properties;
-  properties.type = ui::ime::AssistiveWindowType::kUndoWindow;
-  properties.visible = false;
-  window_visible_ = false;
-  button_highlighted_ = false;
-  suggestion_handler_->SetAssistiveWindowProperties(context_id_, properties,
-                                                    &error);
+  HideUndoWindow();
 
   ui::IMEInputContextHandlerInterface* input_context =
       ui::IMEBridge::Get()->GetInputContextHandler();
@@ -268,6 +231,62 @@
   LogAssistiveAutocorrectDelay(base::TimeTicks::Now() - autocorrect_time_);
 }
 
+void AutocorrectManager::ShowUndoWindow(
+  gfx::Range range, const std::u16string& text) {
+  if (window_visible_) {
+    return;
+  }
+
+  std::string error;
+  const std::u16string autocorrected_text =
+      text.substr(range.start(), range.length());
+  AssistiveWindowProperties properties;
+  properties.type = ui::ime::AssistiveWindowType::kUndoWindow;
+  properties.visible = true;
+  properties.announce_string = l10n_util::GetStringFUTF16(
+      IDS_SUGGESTION_AUTOCORRECT_UNDO_WINDOW_SHOWN, original_text_,
+      autocorrected_text);
+  button_highlighted_ = false;
+  // TODO(b/161490813): Handle error.
+  suggestion_handler_->SetAssistiveWindowProperties(context_id_, properties,
+                                                    &error);
+  LogAssistiveAutocorrectAction(AutocorrectActions::kWindowShown);
+  RecordAssistiveCoverage(AssistiveType::kAutocorrectWindowShown);
+  window_visible_ = true;
+}
+
+void AutocorrectManager::HideUndoWindow() {
+  if (!window_visible_) {
+    return;
+  }
+
+  std::string error;
+  AssistiveWindowProperties properties;
+  properties.type = ui::ime::AssistiveWindowType::kUndoWindow;
+  properties.visible = false;
+  button_highlighted_ = false;
+  // TODO(b/161490813): Handle error.
+  suggestion_handler_->SetAssistiveWindowProperties(context_id_, properties,
+                                                    &error);
+  window_visible_ = false;
+}
+
+void AutocorrectManager::HighlightUndoButton() {
+  if (button_highlighted_) {
+    return;
+  }
+
+  std::string error;
+  auto button = ui::ime::AssistiveWindowButton();
+  button.id = ui::ime::ButtonId::kUndo;
+  button.window_type = ui::ime::AssistiveWindowType::kUndoWindow;
+  button.announce_string = l10n_util::GetStringFUTF16(
+      IDS_SUGGESTION_AUTOCORRECT_UNDO_BUTTON, original_text_);
+  suggestion_handler_->SetButtonHighlighted(context_id_, button, true,
+                                            &error);
+  button_highlighted_ = true;
+}
+
 void AutocorrectManager::OnTextFieldContextualInfoChanged(
     const TextFieldContextualInfo& info) {
   disabled_by_rule_ =
diff --git a/chrome/browser/ash/input_method/autocorrect_manager.h b/chrome/browser/ash/input_method/autocorrect_manager.h
index aee999b..f24e4ef 100644
--- a/chrome/browser/ash/input_method/autocorrect_manager.h
+++ b/chrome/browser/ash/input_method/autocorrect_manager.h
@@ -77,6 +77,16 @@
 
   void OnTextFieldContextualInfoChanged(const TextFieldContextualInfo& info);
 
+  // Hides undo window if there is any visible.
+  void HideUndoWindow();
+
+  // Shows undo window and record the relevant metric if undo window is
+  // not already visible.
+  void ShowUndoWindow(gfx::Range range, const std::u16string& text);
+
+  // Highlights undo button of undo window if it is visible.
+  void HighlightUndoButton();
+
   SuggestionHandlerInterface* suggestion_handler_;
   int context_id_ = 0;
   int key_presses_until_underline_hide_ = 0;
diff --git a/chrome/browser/ash/input_method/autocorrect_manager_unittest.cc b/chrome/browser/ash/input_method/autocorrect_manager_unittest.cc
index 5ec5f37..f369124f 100644
--- a/chrome/browser/ash/input_method/autocorrect_manager_unittest.cc
+++ b/chrome/browser/ash/input_method/autocorrect_manager_unittest.cc
@@ -25,6 +25,28 @@
 
 using ::testing::_;
 
+// A helper to create properties for hidden undo window.
+AssistiveWindowProperties CreateHiddenUndoWindowProperties() {
+  AssistiveWindowProperties window_properties;
+  window_properties.type = ui::ime::AssistiveWindowType::kUndoWindow;
+  window_properties.visible = false;
+  return window_properties;
+}
+
+// A helper to create properties for shown undo window.
+AssistiveWindowProperties CreateVisibleUndoWindowProperties(
+    const std::u16string& original_text,
+    const std::u16string& autocorrected_text) {
+  AssistiveWindowProperties window_properties;
+  window_properties.type = ui::ime::AssistiveWindowType::kUndoWindow;
+  window_properties.visible = true;
+  window_properties.announce_string = l10n_util::GetStringFUTF16(
+      IDS_SUGGESTION_AUTOCORRECT_UNDO_WINDOW_SHOWN, original_text,
+      autocorrected_text);
+  return window_properties;
+}
+
+// A helper for creating key event.
 ui::KeyEvent CreateKeyEvent(ui::DomKey key, ui::DomCode code) {
   return ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_UNKNOWN, code, ui::EF_NONE,
                       key, ui::EventTimeForNow());
@@ -116,11 +138,8 @@
                                    /*anchor_pos=*/4);
   manager.HandleAutocorrect(gfx::Range(0, 3), u"teh", u"the");
 
-  AssistiveWindowProperties properties;
-  properties.type = ui::ime::AssistiveWindowType::kUndoWindow;
-  properties.visible = true;
-  properties.announce_string = l10n_util::GetStringFUTF16(
-      IDS_SUGGESTION_AUTOCORRECT_UNDO_WINDOW_SHOWN, u"teh", u"the");
+  AssistiveWindowProperties properties =
+      CreateVisibleUndoWindowProperties(u"teh", u"the");
   EXPECT_CALL(mock_suggestion_handler,
               SetAssistiveWindowProperties(_, properties, _));
 
@@ -140,17 +159,13 @@
   {
     ::testing::InSequence seq;
 
-    AssistiveWindowProperties shown_properties;
-    shown_properties.type = ui::ime::AssistiveWindowType::kUndoWindow;
-    shown_properties.visible = true;
-    shown_properties.announce_string = l10n_util::GetStringFUTF16(
-        IDS_SUGGESTION_AUTOCORRECT_UNDO_WINDOW_SHOWN, u"teh", u"the");
+    AssistiveWindowProperties shown_properties =
+        CreateVisibleUndoWindowProperties(u"teh", u"the");
     EXPECT_CALL(mock_suggestion_handler,
                 SetAssistiveWindowProperties(_, shown_properties, _));
 
-    AssistiveWindowProperties hidden_properties;
-    hidden_properties.type = ui::ime::AssistiveWindowType::kUndoWindow;
-    hidden_properties.visible = false;
+    AssistiveWindowProperties hidden_properties =
+        CreateHiddenUndoWindowProperties();
     EXPECT_CALL(mock_suggestion_handler,
                 SetAssistiveWindowProperties(_, hidden_properties, _));
   }
diff --git a/chrome/browser/ash/plugin_vm/plugin_vm_installer.cc b/chrome/browser/ash/plugin_vm/plugin_vm_installer.cc
index 1a0e96c..7b2157bf 100644
--- a/chrome/browser/ash/plugin_vm/plugin_vm_installer.cc
+++ b/chrome/browser/ash/plugin_vm/plugin_vm_installer.cc
@@ -304,8 +304,8 @@
   }
   const base::Value* plugin_vm_image_hash_ptr =
       profile_->GetPrefs()
-          ->GetDictionary(prefs::kPluginVmImage)
-          ->FindKey(prefs::kPluginVmImageHashKeyName);
+          ->GetValueDict(prefs::kPluginVmImage)
+          .Find(prefs::kPluginVmImageHashKeyName);
   if (!plugin_vm_image_hash_ptr) {
     LOG(ERROR) << "Hash of PluginVm image is not specified";
     return false;
@@ -959,8 +959,8 @@
 
 GURL PluginVmInstaller::GetPluginVmImageDownloadUrl() {
   const base::Value* url_ptr = profile_->GetPrefs()
-                                   ->GetDictionary(prefs::kPluginVmImage)
-                                   ->FindKey(prefs::kPluginVmImageUrlKeyName);
+                                   ->GetValueDict(prefs::kPluginVmImage)
+                                   .Find(prefs::kPluginVmImageUrlKeyName);
   if (!url_ptr) {
     LOG(ERROR) << "Url to PluginVm image is not specified";
     return GURL();
diff --git a/chrome/browser/ash/system_extensions/BUILD.gn b/chrome/browser/ash/system_extensions/BUILD.gn
index 0228f47c..50a9901 100644
--- a/chrome/browser/ash/system_extensions/BUILD.gn
+++ b/chrome/browser/ash/system_extensions/BUILD.gn
@@ -19,6 +19,8 @@
     "system_extensions_internals_page_handler.h",
     "system_extensions_mutable_registry.cc",
     "system_extensions_mutable_registry.h",
+    "system_extensions_persistence_manager.cc",
+    "system_extensions_persistence_manager.h",
     "system_extensions_profile_utils.cc",
     "system_extensions_profile_utils.h",
     "system_extensions_provider.cc",
@@ -52,6 +54,7 @@
     "//chrome/common:constants",
     "//components/keyed_service/content",
     "//components/keyed_service/core",
+    "//components/pref_registry",
     "//components/user_manager",
     "//content/public/browser",
     "//services/data_decoder/public/cpp",
@@ -78,11 +81,18 @@
 source_set("unit_tests") {
   testonly = true
 
-  sources = [ "system_extensions_sandboxed_unpacker_unittest.cc" ]
+  sources = [
+    "system_extensions_persistence_manager_unittest.cc",
+    "system_extensions_sandboxed_unpacker_unittest.cc",
+  ]
   deps = [
     ":system_extensions",
     "//base",
     "//base/test:test_support",
+    "//chrome/browser/profiles:profile",
+    "//chrome/test:test_support",
+    "//components/prefs:prefs",
+    "//components/sync_preferences:test_support",
     "//services/data_decoder/public/cpp",
     "//services/data_decoder/public/cpp:test_support",
     "//skia",
diff --git a/chrome/browser/ash/system_extensions/system_extension.h b/chrome/browser/ash/system_extensions/system_extension.h
index fce13e52..40d329db 100644
--- a/chrome/browser/ash/system_extensions/system_extension.h
+++ b/chrome/browser/ash/system_extensions/system_extension.h
@@ -8,6 +8,7 @@
 #include <array>
 
 #include "base/strings/string_piece_forward.h"
+#include "base/values.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
@@ -57,6 +58,9 @@
   // The System Extension's base URL derived from the type and the id e.g.
   // `chrome-untrusted://system-extension-echo-1234/`
   GURL base_url;
+
+  // Parsed JSON that was used to installed the System Extension.
+  base::Value::Dict manifest;
 };
 
 }  // namespace ash
diff --git a/chrome/browser/ash/system_extensions/system_extensions_browsertest.cc b/chrome/browser/ash/system_extensions/system_extensions_browsertest.cc
index 11fc4176..d468a7c 100644
--- a/chrome/browser/ash/system_extensions/system_extensions_browsertest.cc
+++ b/chrome/browser/ash/system_extensions/system_extensions_browsertest.cc
@@ -13,6 +13,7 @@
 #include "base/test/scoped_feature_list.h"
 #include "base/threading/thread_restrictions.h"
 #include "chrome/browser/ash/system_extensions/system_extensions_install_manager.h"
+#include "chrome/browser/ash/system_extensions/system_extensions_persistence_manager.h"
 #include "chrome/browser/ash/system_extensions/system_extensions_profile_utils.h"
 #include "chrome/browser/ash/system_extensions/system_extensions_provider.h"
 #include "chrome/browser/ash/system_extensions/system_extensions_provider_factory.h"
@@ -21,6 +22,7 @@
 #include "chrome/common/chrome_paths.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "components/prefs/pref_service.h"
 #include "content/public/browser/navigation_entry.h"
 #include "content/public/browser/service_worker_context.h"
 #include "content/public/browser/storage_partition.h"
@@ -34,6 +36,16 @@
 
 constexpr SystemExtensionId kTestSystemExtensionId = {1, 2, 3, 4};
 
+constexpr char kTestSystemExtensionManifest[] = R"({
+   "companion_web_app_url": "https://example.com",
+   "id": "01020304",
+   "name": "Sample System Web Extension",
+   "service_worker_url": "/sw.js",
+   "short_name": "Sample SWX",
+   "type": "echo"
+}
+)";
+
 constexpr char kTestSystemExtensionIndexURL[] =
     "chrome-untrusted://system-extension-echo-01020304/html/index.html";
 
@@ -210,6 +222,13 @@
               extension_ids);
     EXPECT_TRUE(registry.GetById(kTestSystemExtensionId));
 
+    // Test we persisted the System Extension.
+    absl::optional<SystemExtensionPersistenceInfo> persistence_info =
+        provider.persistence_manager().Get(kTestSystemExtensionId);
+    ASSERT_TRUE(persistence_info);
+    EXPECT_EQ(kTestSystemExtensionManifest,
+              persistence_info->manifest.DebugString());
+
     auto* tab = browser()->tab_strip_model()->GetActiveWebContents();
     {
       ASSERT_TRUE(ui_test_utils::NavigateToURL(
@@ -300,6 +319,11 @@
   EXPECT_TRUE(registry.GetIds().empty());
   EXPECT_FALSE(registry.GetById(kTestSystemExtensionId));
 
+  // Tests that the System Extension is no longer in persistent storage.
+  absl::optional<SystemExtensionPersistenceInfo> persistence_info =
+      provider.persistence_manager().Get(kTestSystemExtensionId);
+  EXPECT_FALSE(persistence_info);
+
   // Test that navigating to the System Extension's resources fails.
   auto* tab = browser()->tab_strip_model()->GetActiveWebContents();
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(),
diff --git a/chrome/browser/ash/system_extensions/system_extensions_install_manager.cc b/chrome/browser/ash/system_extensions/system_extensions_install_manager.cc
index fadb976..e6251d22 100644
--- a/chrome/browser/ash/system_extensions/system_extensions_install_manager.cc
+++ b/chrome/browser/ash/system_extensions/system_extensions_install_manager.cc
@@ -17,6 +17,7 @@
 #include "base/strings/string_util.h"
 #include "base/values.h"
 #include "chrome/browser/ash/system_extensions/system_extension.h"
+#include "chrome/browser/ash/system_extensions/system_extensions_persistence_manager.h"
 #include "chrome/browser/ash/system_extensions/system_extensions_profile_utils.h"
 #include "chrome/browser/ash/system_extensions/system_extensions_registry_manager.h"
 #include "chrome/browser/ash/system_extensions/system_extensions_webui_config.h"
@@ -38,10 +39,12 @@
 SystemExtensionsInstallManager::SystemExtensionsInstallManager(
     Profile* profile,
     SystemExtensionsRegistryManager& registry_manager,
-    SystemExtensionsRegistry& registry)
+    SystemExtensionsRegistry& registry,
+    SystemExtensionsPersistenceManager& persistence_manager)
     : profile_(profile),
       registry_manager_(registry_manager),
-      registry_(registry) {
+      registry_(registry),
+      persistence_manager_(persistence_manager) {
   InstallFromCommandLineIfNecessary();
 }
 
@@ -130,7 +133,10 @@
   content::WebUIConfigMap::GetInstance().AddUntrustedWebUIConfig(
       std::move(config));
 
-  // Installation Step #4: Add the System Extension to the registry.
+  // Installation Step #4: Persist the System Extension across restarts.
+  persistence_manager_->Persist(system_extension);
+
+  // Installation Step #5: Add the System Extension to the registry.
   SystemExtensionId id = system_extension.id;
   registry_manager_->AddSystemExtension(std::move(system_extension));
 
@@ -154,7 +160,7 @@
       blink::mojom::ServiceWorkerUpdateViaCache::kImports);
   blink::StorageKey key(url::Origin::Create(options.scope));
 
-  // Installation Step #5: Register a Service Worker for the System Extension.
+  // Installation Step #6: Register a Service Worker for the System Extension.
   auto* worker_context =
       profile_->GetDefaultStoragePartition()->GetServiceWorkerContext();
   worker_context->RegisterServiceWorker(
@@ -187,8 +193,6 @@
   const GURL& scope = system_extension->base_url;
   const url::Origin& origin = url::Origin::Create(system_extension->base_url);
 
-  // The un-installation steps are in reverse order of the installation steps.
-
   // Uninstallation Step #1: Unregister the Service Worker.
   auto* worker_context =
       profile_->GetDefaultStoragePartition()->GetServiceWorkerContext();
@@ -202,10 +206,13 @@
   // Uninstallation Step #2: Remove the WebUIConfig for the System Extension.
   content::WebUIConfigMap::GetInstance().RemoveConfig(origin);
 
-  // Uninstallation Step #3: Remove System Extension from the registry.
+  // Installation Step #3: Remove the System Extension from persistent storage.
+  persistence_manager_->Delete(system_extension_id);
+
+  // Uninstallation Step #4: Remove System Extension from the registry.
   registry_manager_->RemoveSystemExtension(system_extension_id);
 
-  // Uninstallation Step #4: Delete the System Extension assets.
+  // Uninstallation Step #5: Delete the System Extension assets.
   io_helper_.AsyncCall(&IOHelper::RemoveExtensionAssets)
       .WithArgs(GetDirectoryForSystemExtension(*profile_, system_extension_id))
       .Then(base::BindOnce(&SystemExtensionsInstallManager::NotifyAssetsRemoved,
diff --git a/chrome/browser/ash/system_extensions/system_extensions_install_manager.h b/chrome/browser/ash/system_extensions/system_extensions_install_manager.h
index fb12687..c8cd252 100644
--- a/chrome/browser/ash/system_extensions/system_extensions_install_manager.h
+++ b/chrome/browser/ash/system_extensions/system_extensions_install_manager.h
@@ -22,6 +22,7 @@
 
 namespace ash {
 
+class SystemExtensionsPersistenceManager;
 class SystemExtensionsRegistry;
 class SystemExtensionsRegistryManager;
 
@@ -51,7 +52,8 @@
   SystemExtensionsInstallManager(
       Profile* profile,
       SystemExtensionsRegistryManager& registry_manager,
-      SystemExtensionsRegistry& registry);
+      SystemExtensionsRegistry& registry,
+      SystemExtensionsPersistenceManager& persistence_manager);
   SystemExtensionsInstallManager(const SystemExtensionsInstallManager&) =
       delete;
   SystemExtensionsInstallManager& operator=(
@@ -129,6 +131,7 @@
   // destroyed before the classes below.
   const raw_ref<SystemExtensionsRegistryManager> registry_manager_;
   const raw_ref<SystemExtensionsRegistry> registry_;
+  const raw_ref<SystemExtensionsPersistenceManager> persistence_manager_;
 
   std::map<SystemExtensionId, SystemExtension> system_extensions_;
 
diff --git a/chrome/browser/ash/system_extensions/system_extensions_persistence_manager.cc b/chrome/browser/ash/system_extensions/system_extensions_persistence_manager.cc
new file mode 100644
index 0000000..3d906990
--- /dev/null
+++ b/chrome/browser/ash/system_extensions/system_extensions_persistence_manager.cc
@@ -0,0 +1,84 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/system_extensions/system_extensions_persistence_manager.h"
+
+#include "base/logging.h"
+#include "chrome/browser/profiles/profile.h"
+#include "components/pref_registry/pref_registry_syncable.h"
+#include "components/prefs/scoped_user_pref_update.h"
+
+namespace ash {
+
+namespace prefs {
+static constexpr char kPersistedSystemExtensions[] =
+    "system_extensions.persisted";
+}  // namespace prefs
+
+namespace {
+static constexpr char kSystemExtensionManifest[] = "manifest";
+}  // namespace
+
+// static
+void SystemExtensionsPersistenceManager::RegisterProfilePrefs(
+    user_prefs::PrefRegistrySyncable* registry) {
+  registry->RegisterDictionaryPref(prefs::kPersistedSystemExtensions);
+}
+
+SystemExtensionsPersistenceManager::SystemExtensionsPersistenceManager(
+    Profile* profile)
+    : profile_(profile) {}
+
+SystemExtensionsPersistenceManager::~SystemExtensionsPersistenceManager() =
+    default;
+
+void SystemExtensionsPersistenceManager::Persist(
+    const SystemExtension& system_extension) {
+  DictionaryPrefUpdate update(profile_->GetPrefs(),
+                              prefs::kPersistedSystemExtensions);
+  base::Value::Dict& persisted_system_extensions_map = update->GetDict();
+
+  base::Value::Dict persisted_system_extension;
+  persisted_system_extension.Set(kSystemExtensionManifest,
+                                 system_extension.manifest.Clone());
+
+  persisted_system_extensions_map.Set(
+      SystemExtension::IdToString(system_extension.id),
+      std::move(persisted_system_extension));
+}
+
+void SystemExtensionsPersistenceManager::Delete(
+    const SystemExtensionId& system_extension_id) {
+  DictionaryPrefUpdate update(profile_->GetPrefs(),
+                              prefs::kPersistedSystemExtensions);
+  update->GetDict().Remove(SystemExtension::IdToString(system_extension_id));
+}
+
+absl::optional<SystemExtensionPersistenceInfo>
+SystemExtensionsPersistenceManager::Get(
+    const SystemExtensionId& system_extension_id) {
+  auto* prefs = profile_->GetPrefs();
+  const base::Value::Dict& persisted_system_extensions_map =
+      prefs->GetValueDict(prefs::kPersistedSystemExtensions);
+
+  const base::Value::Dict* persisted_system_extension =
+      persisted_system_extensions_map.FindDict(
+          SystemExtension::IdToString(system_extension_id));
+  if (!persisted_system_extension)
+    return absl::nullopt;
+
+  const base::Value::Dict* manifest_pref =
+      persisted_system_extension->FindDict(kSystemExtensionManifest);
+  if (!manifest_pref)
+    return absl::nullopt;
+
+  absl::optional<SystemExtensionPersistenceInfo> info;
+  info.emplace();
+  info->id = system_extension_id;
+  info->manifest = manifest_pref->Clone();
+
+  return info;
+}
+
+}  // namespace ash
diff --git a/chrome/browser/ash/system_extensions/system_extensions_persistence_manager.h b/chrome/browser/ash/system_extensions/system_extensions_persistence_manager.h
new file mode 100644
index 0000000..4bd243d
--- /dev/null
+++ b/chrome/browser/ash/system_extensions/system_extensions_persistence_manager.h
@@ -0,0 +1,60 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ASH_SYSTEM_EXTENSIONS_SYSTEM_EXTENSIONS_PERSISTENCE_MANAGER_H_
+#define CHROME_BROWSER_ASH_SYSTEM_EXTENSIONS_SYSTEM_EXTENSIONS_PERSISTENCE_MANAGER_H_
+
+#include "base/memory/raw_ptr.h"
+#include "chrome/browser/ash/system_extensions/system_extension.h"
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
+class Profile;
+
+namespace ash {
+
+struct SystemExtension;
+
+// Holds persisted information for a System Extension.
+struct SystemExtensionPersistenceInfo {
+  SystemExtensionId id;
+  base::Value::Dict manifest;
+};
+
+// Manages persisting System Extensions to disk so that they can be loaded at
+// startup. This only includes information about System Extension instances, not
+// their resources or assets. See `SystemExtensionPersistenceInfo`.
+class SystemExtensionsPersistenceManager {
+ public:
+  // Registers prefs used for persisting System Extension information to disk.
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
+
+  explicit SystemExtensionsPersistenceManager(Profile* profile);
+  SystemExtensionsPersistenceManager(
+      const SystemExtensionsPersistenceManager&) = delete;
+  SystemExtensionsPersistenceManager& operator=(
+      const SystemExtensionsPersistenceManager&) = delete;
+  ~SystemExtensionsPersistenceManager();
+
+  // Stores |system_extension| in persistent storage.
+  void Persist(const SystemExtension& system_extension);
+
+  // Deletes |system_extension| from persistent storage.
+  void Delete(const SystemExtensionId& system_extension_id);
+
+  // Returns the System Extension with |system_extension_id| if it's in
+  // persistent storage, or nullopt if it's not.
+  absl::optional<SystemExtensionPersistenceInfo> Get(
+      const SystemExtensionId& system_extension_id);
+
+ private:
+  // Safe to hold a pointer because the parent class is owned by Profile.
+  raw_ptr<Profile> profile_;
+};
+
+}  // namespace ash
+
+#endif  // CHROME_BROWSER_ASH_SYSTEM_EXTENSIONS_SYSTEM_EXTENSIONS_PERSISTENCE_MANAGER_H_
diff --git a/chrome/browser/ash/system_extensions/system_extensions_persistence_manager_unittest.cc b/chrome/browser/ash/system_extensions/system_extensions_persistence_manager_unittest.cc
new file mode 100644
index 0000000..e724723
--- /dev/null
+++ b/chrome/browser/ash/system_extensions/system_extensions_persistence_manager_unittest.cc
@@ -0,0 +1,123 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/system_extensions/system_extensions_persistence_manager.h"
+
+#include "chrome/browser/ash/system_extensions/system_extension.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "components/prefs/pref_service.h"
+#include "components/sync_preferences/testing_pref_service_syncable.h"
+
+namespace ash {
+
+namespace {
+
+constexpr char kTestTypeStr[] = "echo";
+constexpr SystemExtensionId kTestId = {1, 2, 3, 4};
+constexpr char kTestIdStr[] = "01020304";
+constexpr char kTestName[] = "Sample System Web Extension";
+constexpr char kTestShortName[] = "Sample SWX";
+constexpr char kTestServiceWorkerURL[] = "/sw.js";
+
+class SystemExtensionsPersistenceManagerTest
+    : public ChromeRenderViewHostTestHarness {
+ public:
+  SystemExtensionsPersistenceManagerTest() {
+    test_system_extension_.id = kTestId;
+    test_system_extension_.manifest.Set("type", kTestTypeStr);
+    test_system_extension_.manifest.Set("id", kTestIdStr);
+    test_system_extension_.manifest.Set("name", kTestName);
+    test_system_extension_.manifest.Set("short_name", kTestShortName);
+    test_system_extension_.manifest.Set("service_worker_url",
+                                        kTestServiceWorkerURL);
+  }
+
+  void SetUp() override {
+    ChromeRenderViewHostTestHarness::SetUp();
+
+    SystemExtensionsPersistenceManager::RegisterProfilePrefs(
+        profile()->GetTestingPrefService()->registry());
+  }
+
+ protected:
+  const SystemExtension& test_system_extension() {
+    return test_system_extension_;
+  }
+
+  const base::Value::Dict& test_manifest() {
+    return test_system_extension_.manifest;
+  }
+
+ private:
+  SystemExtension test_system_extension_;
+};
+
+}  // namespace
+
+// Tests that we are writing and removing prefs as we persist and delete
+// System Extensions.
+TEST_F(SystemExtensionsPersistenceManagerTest, WriteAndRemovePrefs) {
+  SystemExtensionsPersistenceManager manager(profile());
+  manager.Persist(test_system_extension());
+
+  // Test that the extension was saved into a pref.
+  auto* prefs = profile()->GetPrefs();
+  {
+    const base::Value::Dict& persisted_system_extensions_map =
+        prefs->GetValueDict("system_extensions.persisted");
+    auto* persisted_system_extension =
+        persisted_system_extensions_map.FindDict(kTestIdStr);
+    EXPECT_EQ(*persisted_system_extension->FindDict("manifest"),
+              test_manifest());
+  }
+
+  // Test the API returns the correct value.
+  absl::optional<SystemExtensionPersistenceInfo> persistence_info =
+      manager.Get(kTestId);
+  EXPECT_EQ(persistence_info->manifest, test_manifest());
+
+  manager.Delete(kTestId);
+
+  // Test that the System Extension was removed from prefs.
+  {
+    const base::Value::Dict& persisted_system_extensions_map =
+        prefs->GetValueDict("system_extensions.persisted");
+    auto* persisted_system_extension =
+        persisted_system_extensions_map.FindDict(kTestIdStr);
+    EXPECT_FALSE(persisted_system_extension);
+  }
+
+  // Test that the API no longer returns the System Extension.
+  EXPECT_FALSE(manager.Get(kTestId));
+}
+
+// Tests that persisting a System Extension with the same id twice
+// overwrites the original System Extension.
+TEST_F(SystemExtensionsPersistenceManagerTest, PersistTwice) {
+  SystemExtensionsPersistenceManager manager(profile());
+  manager.Persist(test_system_extension());
+
+  // The second System Extension has the same id but a different name.
+  SystemExtension second_system_extension;
+  second_system_extension.id = kTestId;
+  second_system_extension.manifest = test_manifest().Clone();
+  second_system_extension.manifest.Set("name", "Second System Extension");
+
+  manager.Persist(second_system_extension);
+
+  // Test that the saved manifest is the correct one i.e. from the second
+  // System Extension.
+  absl::optional<SystemExtensionPersistenceInfo> persistence_info =
+      manager.Get(kTestId);
+  EXPECT_EQ(persistence_info->manifest, second_system_extension.manifest);
+}
+
+// Tests deleting a non-existent System Extension doesn't crash.
+TEST_F(SystemExtensionsPersistenceManagerTest, RemoveNonExistent) {
+  SystemExtensionsPersistenceManager manager(profile());
+  manager.Delete(kTestId);
+}
+
+}  // namespace ash
diff --git a/chrome/browser/ash/system_extensions/system_extensions_provider.cc b/chrome/browser/ash/system_extensions/system_extensions_provider.cc
index 9bbbf107..04c575f0 100644
--- a/chrome/browser/ash/system_extensions/system_extensions_provider.cc
+++ b/chrome/browser/ash/system_extensions/system_extensions_provider.cc
@@ -10,6 +10,7 @@
 #include "base/feature_list.h"
 #include "chrome/browser/ash/system_extensions/system_extension.h"
 #include "chrome/browser/ash/system_extensions/system_extensions_install_manager.h"
+#include "chrome/browser/ash/system_extensions/system_extensions_persistence_manager.h"
 #include "chrome/browser/ash/system_extensions/system_extensions_profile_utils.h"
 #include "chrome/browser/ash/system_extensions/system_extensions_provider_factory.h"
 #include "chrome/browser/ash/system_extensions/system_extensions_registry_manager.h"
@@ -35,9 +36,12 @@
 }
 
 SystemExtensionsProvider::SystemExtensionsProvider(Profile* profile) {
+  persistence_manager_ =
+      std::make_unique<SystemExtensionsPersistenceManager>(profile);
   registry_manager_ = std::make_unique<SystemExtensionsRegistryManager>();
   install_manager_ = std::make_unique<SystemExtensionsInstallManager>(
-      profile, *registry_manager_, registry_manager_->registry());
+      profile, *registry_manager_, registry_manager_->registry(),
+      *persistence_manager_);
 }
 
 SystemExtensionsProvider::~SystemExtensionsProvider() = default;
diff --git a/chrome/browser/ash/system_extensions/system_extensions_provider.h b/chrome/browser/ash/system_extensions/system_extensions_provider.h
index 7dfbf49..31456b8 100644
--- a/chrome/browser/ash/system_extensions/system_extensions_provider.h
+++ b/chrome/browser/ash/system_extensions/system_extensions_provider.h
@@ -15,6 +15,8 @@
 
 namespace ash {
 
+class SystemExtensionsPersistenceManager;
+
 // Manages the installation, storage, and execution of System Extensions.
 class SystemExtensionsProvider : public KeyedService {
  public:
@@ -43,6 +45,10 @@
     return *registry_manager_;
   }
 
+  SystemExtensionsPersistenceManager& persistence_manager() {
+    return *persistence_manager_;
+  }
+
   SystemExtensionsInstallManager& install_manager() {
     return *install_manager_;
   }
@@ -57,6 +63,7 @@
 
  private:
   std::unique_ptr<SystemExtensionsRegistryManager> registry_manager_;
+  std::unique_ptr<SystemExtensionsPersistenceManager> persistence_manager_;
   std::unique_ptr<SystemExtensionsInstallManager> install_manager_;
 };
 
diff --git a/chrome/browser/ash/system_extensions/system_extensions_provider_factory.cc b/chrome/browser/ash/system_extensions/system_extensions_provider_factory.cc
index e1a8796..47754d66 100644
--- a/chrome/browser/ash/system_extensions/system_extensions_provider_factory.cc
+++ b/chrome/browser/ash/system_extensions/system_extensions_provider_factory.cc
@@ -6,6 +6,7 @@
 
 #include "base/no_destructor.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
+#include "chrome/browser/ash/system_extensions/system_extensions_persistence_manager.h"
 #include "chrome/browser/ash/system_extensions/system_extensions_profile_utils.h"
 #include "chrome/browser/ash/system_extensions/system_extensions_provider.h"
 #include "chrome/browser/profiles/incognito_helpers.h"
@@ -47,6 +48,11 @@
   return true;
 }
 
+void SystemExtensionsProviderFactory::RegisterProfilePrefs(
+    user_prefs::PrefRegistrySyncable* registry) {
+  SystemExtensionsPersistenceManager::RegisterProfilePrefs(registry);
+}
+
 content::BrowserContext*
 SystemExtensionsProviderFactory::GetBrowserContextToUse(
     content::BrowserContext* context) const {
diff --git a/chrome/browser/ash/system_extensions/system_extensions_provider_factory.h b/chrome/browser/ash/system_extensions/system_extensions_provider_factory.h
index dd1168c..4b198f5 100644
--- a/chrome/browser/ash/system_extensions/system_extensions_provider_factory.h
+++ b/chrome/browser/ash/system_extensions/system_extensions_provider_factory.h
@@ -46,6 +46,8 @@
   bool ServiceIsCreatedWithBrowserContext() const override;
   content::BrowserContext* GetBrowserContextToUse(
       content::BrowserContext* context) const override;
+  void RegisterProfilePrefs(
+      user_prefs::PrefRegistrySyncable* registry) override;
 };
 
 }  // namespace ash
diff --git a/chrome/browser/ash/system_extensions/system_extensions_sandboxed_unpacker.cc b/chrome/browser/ash/system_extensions/system_extensions_sandboxed_unpacker.cc
index c2a19e1..97a4bdd 100644
--- a/chrome/browser/ash/system_extensions/system_extensions_sandboxed_unpacker.cc
+++ b/chrome/browser/ash/system_extensions/system_extensions_sandboxed_unpacker.cc
@@ -95,9 +95,16 @@
     return;
   }
 
+  if (!value_or_error->is_dict()) {
+    std::move(callback).Run(
+        SystemExtensionsInstallStatus::kFailedJsonErrorParsingManifest);
+    return;
+  }
+
   base::Value& parsed_manifest = *value_or_error;
 
   SystemExtension system_extension;
+  system_extension.manifest = parsed_manifest.GetDict().Clone();
 
   // Parse mandatory fields.
 
diff --git a/chrome/browser/ash/telemetry_extension/diagnostics_service_ash.cc b/chrome/browser/ash/telemetry_extension/diagnostics_service_ash.cc
index e421a31..d5552045 100644
--- a/chrome/browser/ash/telemetry_extension/diagnostics_service_ash.cc
+++ b/chrome/browser/ash/telemetry_extension/diagnostics_service_ash.cc
@@ -9,12 +9,14 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/memory/ptr_util.h"
 #include "chrome/browser/ash/telemetry_extension/diagnostics_service_converters.h"
 #include "chromeos/ash/services/cros_healthd/public/cpp/service_connection.h"
 #include "chromeos/ash/services/cros_healthd/public/mojom/cros_healthd_diagnostics.mojom.h"
 #include "chromeos/ash/services/cros_healthd/public/mojom/nullable_primitives.mojom.h"
 #include "chromeos/crosapi/mojom/diagnostics_service.mojom.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
+#include "mojo/public/cpp/bindings/remote.h"
 
 namespace ash {
 
@@ -30,8 +32,9 @@
     return test_factory_->CreateInstance(std::move(receiver));
   }
 
-  return base::WrapUnique<DiagnosticsServiceAsh>(
-      new DiagnosticsServiceAsh(std::move(receiver)));
+  auto diagnostics_service = std::make_unique<DiagnosticsServiceAsh>();
+  diagnostics_service->BindReceiver(std::move(receiver));
+  return diagnostics_service;
 }
 
 // static
@@ -41,12 +44,15 @@
 
 DiagnosticsServiceAsh::Factory::~Factory() = default;
 
-DiagnosticsServiceAsh::DiagnosticsServiceAsh(
-    mojo::PendingReceiver<crosapi::mojom::DiagnosticsService> receiver)
-    : receiver_(this, std::move(receiver)) {}
+DiagnosticsServiceAsh::DiagnosticsServiceAsh() = default;
 
 DiagnosticsServiceAsh::~DiagnosticsServiceAsh() = default;
 
+void DiagnosticsServiceAsh::BindReceiver(
+    mojo::PendingReceiver<crosapi::mojom::DiagnosticsService> receiver) {
+  receivers_.Add(this, std::move(receiver));
+}
+
 cros_healthd::mojom::CrosHealthdDiagnosticsService*
 DiagnosticsServiceAsh::GetService() {
   if (!service_ || !service_.is_connected()) {
diff --git a/chrome/browser/ash/telemetry_extension/diagnostics_service_ash.h b/chrome/browser/ash/telemetry_extension/diagnostics_service_ash.h
index 0450e79..3f7c37e6 100644
--- a/chrome/browser/ash/telemetry_extension/diagnostics_service_ash.h
+++ b/chrome/browser/ash/telemetry_extension/diagnostics_service_ash.h
@@ -10,7 +10,7 @@
 #include "chromeos/ash/services/cros_healthd/public/mojom/cros_healthd.mojom.h"
 #include "chromeos/crosapi/mojom/diagnostics_service.mojom.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
-#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "mojo/public/cpp/bindings/remote.h"
 
 namespace ash {
@@ -39,13 +39,15 @@
     static Factory* test_factory_;
   };
 
+  DiagnosticsServiceAsh();
   DiagnosticsServiceAsh(const DiagnosticsServiceAsh&) = delete;
   DiagnosticsServiceAsh& operator=(const DiagnosticsServiceAsh&) = delete;
   ~DiagnosticsServiceAsh() override;
 
- private:
-  explicit DiagnosticsServiceAsh(
+  void BindReceiver(
       mojo::PendingReceiver<crosapi::mojom::DiagnosticsService> receiver);
+
+ private:
   // Ensures that |service_| created and connected to the
   // CrosHealthdDiagnosticsService.
   cros_healthd::mojom::CrosHealthdDiagnosticsService* GetService();
@@ -106,7 +108,9 @@
   // interface pipe before destroying pending response callbacks owned by
   // |service_|. It is an error to drop response callbacks which still
   // correspond to an open interface pipe.
-  mojo::Receiver<crosapi::mojom::DiagnosticsService> receiver_;
+  //
+  // Support any number of connections.
+  mojo::ReceiverSet<crosapi::mojom::DiagnosticsService> receivers_;
 };
 
 }  // namespace ash
diff --git a/chrome/browser/autofill_assistant/common_dependencies_chrome.cc b/chrome/browser/autofill_assistant/common_dependencies_chrome.cc
index abf9247f..47596718 100644
--- a/chrome/browser/autofill_assistant/common_dependencies_chrome.cc
+++ b/chrome/browser/autofill_assistant/common_dependencies_chrome.cc
@@ -86,6 +86,23 @@
          signin::Tribool::kTrue;
 }
 
+bool CommonDependenciesChrome::IsAllowedForMachineLearning(
+    content::BrowserContext* browser_context) const {
+  DCHECK(browser_context);
+  signin::IdentityManager* identity_manager =
+      IdentityManagerFactory::GetForProfile(
+          Profile::FromBrowserContext(browser_context));
+  if (!identity_manager) {
+    return true;
+  }
+
+  std::string gaia_id =
+      identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSync).gaia;
+  return identity_manager->FindExtendedAccountInfoByGaiaId(gaia_id)
+             .capabilities.is_allowed_for_machine_learning() !=
+         signin::Tribool::kFalse;
+}
+
 AnnotateDomModelService*
 CommonDependenciesChrome::GetOrCreateAnnotateDomModelService(
     content::BrowserContext* browser_context) const {
diff --git a/chrome/browser/autofill_assistant/common_dependencies_chrome.h b/chrome/browser/autofill_assistant/common_dependencies_chrome.h
index df27dc66..38321a3 100644
--- a/chrome/browser/autofill_assistant/common_dependencies_chrome.h
+++ b/chrome/browser/autofill_assistant/common_dependencies_chrome.h
@@ -41,6 +41,9 @@
   bool IsSupervisedUser(
       content::BrowserContext* browser_context) const override;
 
+  bool IsAllowedForMachineLearning(
+      content::BrowserContext* browser_context) const override;
+
   // The AnnotateDomModelService is a KeyedService. There is only one per
   // BrowserContext.
   AnnotateDomModelService* GetOrCreateAnnotateDomModelService(
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index c99e44c6..1b33fbb 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -2070,6 +2070,8 @@
     "app_mode/app_session_browser_window_handler.h",
     "app_mode/app_session_metrics_service.cc",
     "app_mode/app_session_metrics_service.h",
+    "app_mode/app_session_policies.cc",
+    "app_mode/app_session_policies.h",
     "app_mode/chrome_kiosk_app_installer.cc",
     "app_mode/chrome_kiosk_app_installer.h",
     "app_mode/chrome_kiosk_app_launcher.cc",
@@ -3472,6 +3474,7 @@
     "../metrics/perf/random_selector_unittest.cc",
     "../policy/default_geolocation_policy_handler_unittest.cc",
     "../ui/browser_finder_chromeos_unittest.cc",
+    "app_mode/app_session_policies_unittest.cc",
     "app_mode/app_session_unittest.cc",
     "app_mode/chrome_kiosk_app_launcher_unittest.cc",
     "app_mode/kiosk_app_service_launcher_unittest.cc",
diff --git a/chrome/browser/chromeos/app_mode/app_session_browser_window_handler.cc b/chrome/browser/chromeos/app_mode/app_session_browser_window_handler.cc
index f9f48cc..cf26175 100644
--- a/chrome/browser/chromeos/app_mode/app_session_browser_window_handler.cc
+++ b/chrome/browser/chromeos/app_mode/app_session_browser_window_handler.cc
@@ -3,11 +3,13 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/chromeos/app_mode/app_session_browser_window_handler.h"
+#include <memory>
 
 #include "base/metrics/histogram_functions.h"
-#include "chrome/browser/chromeos/app_mode/app_session.h"
+#include "chrome/browser/chromeos/app_mode/app_session_policies.h"
 #include "chrome/browser/chromeos/app_mode/kiosk_settings_navigation_throttle.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_navigator.h"
 #include "chrome/browser/ui/browser_window.h"
 
@@ -26,6 +28,8 @@
       on_last_browser_window_closed_callback_(
           on_last_browser_window_closed_callback) {
   BrowserList::AddObserver(this);
+  app_session_policies_ =
+      std::make_unique<AppSessionPolicies>(profile_->GetPrefs());
 }
 
 AppSessionBrowserWindowHandler::~AppSessionBrowserWindowHandler() {
diff --git a/chrome/browser/chromeos/app_mode/app_session_browser_window_handler.h b/chrome/browser/chromeos/app_mode/app_session_browser_window_handler.h
index 6f33a33..d94a75a 100644
--- a/chrome/browser/chromeos/app_mode/app_session_browser_window_handler.h
+++ b/chrome/browser/chromeos/app_mode/app_session_browser_window_handler.h
@@ -8,9 +8,9 @@
 #include "base/callback_forward.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
+#include "chrome/browser/chromeos/app_mode/app_session_policies.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_list_observer.h"
 
 namespace chromeos {
@@ -69,6 +69,9 @@
   // KioskSettingsNavigationThrottle.
   raw_ptr<Browser> settings_browser_ = nullptr;
 
+  // Provides access to app session related policies.
+  std::unique_ptr<AppSessionPolicies> app_session_policies_;
+
   base::WeakPtrFactory<AppSessionBrowserWindowHandler> weak_ptr_factory_{this};
 };
 
diff --git a/chrome/browser/chromeos/app_mode/app_session_policies.cc b/chrome/browser/chromeos/app_mode/app_session_policies.cc
new file mode 100644
index 0000000..57807b4
--- /dev/null
+++ b/chrome/browser/chromeos/app_mode/app_session_policies.cc
@@ -0,0 +1,20 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/app_mode/app_session_policies.h"
+
+#include "chrome/common/pref_names.h"
+
+namespace chromeos {
+
+AppSessionPolicies::AppSessionPolicies(PrefService* pref_service)
+    : pref_service_(pref_service) {
+  DCHECK(pref_service);
+}
+
+bool AppSessionPolicies::IsWindowCreationAllowed() const {
+  return pref_service_->GetBoolean(prefs::kNewWindowsInKioskAllowed);
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/app_mode/app_session_policies.h b/chrome/browser/chromeos/app_mode/app_session_policies.h
new file mode 100644
index 0000000..9f218317
--- /dev/null
+++ b/chrome/browser/chromeos/app_mode/app_session_policies.h
@@ -0,0 +1,27 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_APP_MODE_APP_SESSION_POLICIES_H_
+#define CHROME_BROWSER_CHROMEOS_APP_MODE_APP_SESSION_POLICIES_H_
+
+#include "components/prefs/pref_service.h"
+
+namespace chromeos {
+
+// Helper class for policies related to the kiosk session.
+class AppSessionPolicies {
+ public:
+  explicit AppSessionPolicies(PrefService* pref_service);
+  ~AppSessionPolicies() = default;
+
+  // Returns |false| if |prefs::kNewWindowsInKioskAllowed| preference is not
+  // found in the pref service, otherwise returns its value.
+  bool IsWindowCreationAllowed() const;
+
+ private:
+  raw_ptr<PrefService> pref_service_;
+};
+
+}  // namespace chromeos
+#endif  // CHROME_BROWSER_CHROMEOS_APP_MODE_APP_SESSION_POLICIES_H_
diff --git a/chrome/browser/chromeos/app_mode/app_session_policies_unittest.cc b/chrome/browser/chromeos/app_mode/app_session_policies_unittest.cc
new file mode 100644
index 0000000..79e752ca
--- /dev/null
+++ b/chrome/browser/chromeos/app_mode/app_session_policies_unittest.cc
@@ -0,0 +1,56 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+
+#include "chrome/browser/chromeos/app_mode/app_session_policies.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/test/browser_task_environment.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+
+class AppSessionPolociesTest : public testing::Test {
+ public:
+  AppSessionPolociesTest() {
+    app_session_policies_ = std::make_unique<AppSessionPolicies>(GetPrefs());
+  }
+
+  AppSessionPolociesTest(const AppSessionPolociesTest&) = delete;
+  AppSessionPolociesTest& operator=(const AppSessionPolociesTest&) = delete;
+
+  void TearDown() override {
+    // Clean up all preferenses that we use in tests.
+    GetPrefs()->ClearPref(prefs::kNewWindowsInKioskAllowed);
+  }
+
+  bool IsWindowCreationAllowed() const {
+    return app_session_policies_->IsWindowCreationAllowed();
+  }
+
+  PrefService* GetPrefs() { return profile_.GetPrefs(); }
+
+ private:
+  content::BrowserTaskEnvironment task_environment_;
+  // |profile_| needs to outlive |app_session_policies_|.
+  TestingProfile profile_;
+  std::unique_ptr<AppSessionPolicies> app_session_policies_;
+};
+
+TEST_F(AppSessionPolociesTest, kNewWindowsInKioskAllowedNotSet) {
+  EXPECT_FALSE(IsWindowCreationAllowed());
+}
+
+TEST_F(AppSessionPolociesTest, kNewWindowsInKioskAllowedSetFalse) {
+  GetPrefs()->SetBoolean(prefs::kNewWindowsInKioskAllowed, false);
+  EXPECT_FALSE(IsWindowCreationAllowed());
+}
+
+TEST_F(AppSessionPolociesTest, kNewWindowsInKioskAllowedSetTrue) {
+  GetPrefs()->SetBoolean(prefs::kNewWindowsInKioskAllowed, true);
+  EXPECT_TRUE(IsWindowCreationAllowed());
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/app_mode/app_session_unittest.cc b/chrome/browser/chromeos/app_mode/app_session_unittest.cc
index 2993b64b..7962934 100644
--- a/chrome/browser/chromeos/app_mode/app_session_unittest.cc
+++ b/chrome/browser/chromeos/app_mode/app_session_unittest.cc
@@ -63,9 +63,10 @@
   }
 
   void WebKioskTracksBrowserCreationTest() {
+    // |profile| needs to outlive |app_session|.
+    TestingProfile profile;
     auto app_session =
         std::make_unique<AppSession>(base::DoNothing(), local_state());
-    TestingProfile profile;
 
     Browser::CreateParams params(&profile, true);
     auto app_browser = CreateBrowserWithTestWindowForParams(params);
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/BUILD.gn b/chrome/browser/chromeos/extensions/telemetry/api/BUILD.gn
index 6ff0e79..8ac18ff 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/BUILD.gn
+++ b/chrome/browser/chromeos/extensions/telemetry/api/BUILD.gn
@@ -17,8 +17,14 @@
     "api_guard_delegate.h",
     "base_telemetry_extension_api_guard_function.cc",
     "base_telemetry_extension_api_guard_function.h",
+    "diagnostics_api.cc",
+    "diagnostics_api.h",
+    "diagnostics_api_converters.cc",
+    "diagnostics_api_converters.h",
     "hardware_info_delegate.cc",
     "hardware_info_delegate.h",
+    "remote_diagnostics_service_strategy.cc",
+    "remote_diagnostics_service_strategy.h",
     "remote_probe_service_strategy.cc",
     "remote_probe_service_strategy.h",
     "telemetry_api.cc",
@@ -46,18 +52,7 @@
   ]
 
   if (is_chromeos_ash) {
-    sources += [
-      "diagnostics_api.cc",
-      "diagnostics_api.h",
-      "diagnostics_api_converters.cc",
-      "diagnostics_api_converters.h",
-      "remote_diagnostics_service_strategy.cc",
-      "remote_diagnostics_service_strategy.h",
-    ]
-
     deps += [
-      "//ash/webui/telemetry_extension_ui/mojom",
-      "//ash/webui/telemetry_extension_ui/services:telemetry_services",
       "//chrome/browser/ash/crosapi",
       "//chrome/browser/ash/telemetry_extension",
       "//components/user_manager",
@@ -92,8 +87,10 @@
   testonly = true
   defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ]
   sources = [
+    "base_telemetry_extension_api_guard_function_browsertest.cc",
     "base_telemetry_extension_browser_test.cc",
     "base_telemetry_extension_browser_test.h",
+    "diagnostics_api_browsertest.cc",
     "fake_api_guard_delegate.cc",
     "fake_api_guard_delegate.h",
     "fake_diagnostics_service.cc",
@@ -101,6 +98,7 @@
     "fake_probe_service.cc",
     "fake_probe_service.h",
     "telemetry_api_browsertest.cc",
+    "telemetry_extension_capabilities_browser_test.cc",
   ]
 
   deps = [
@@ -110,6 +108,7 @@
     "//chrome/common/chromeos/extensions",
     "//chrome/test:test_support",
     "//chromeos/crosapi/mojom",
+    "//chromeos/startup",
     "//components/user_manager",
     "//content/test:test_support",
     "//extensions:test_support",
@@ -122,15 +121,14 @@
     "//url",
   ]
 
+  data = [ "//chrome/test/data" ]
+
   if (is_chromeos_ash) {
     sources += [
-      "base_telemetry_extension_api_guard_function_browsertest.cc",
-      "diagnostics_api_browsertest.cc",
       "fake_diagnostics_service_factory.cc",
       "fake_diagnostics_service_factory.h",
       "fake_probe_service_factory.cc",
       "fake_probe_service_factory.h",
-      "telemetry_extension_capabilities_browser_test.cc",
     ]
 
     deps += [
@@ -146,7 +144,10 @@
 
 source_set("unit_tests") {
   testonly = true
-  sources = [ "telemetry_api_converters_unittest.cc" ]
+  sources = [
+    "diagnostics_api_converters_unittest.cc",
+    "telemetry_api_converters_unittest.cc",
+  ]
 
   deps = [
     ":api",
@@ -156,12 +157,6 @@
     "//chromeos/crosapi/mojom",
     "//testing/gtest",
   ]
-
-  if (is_chromeos_ash) {
-    sources += [ "diagnostics_api_converters_unittest.cc" ]
-
-    deps += [ "//ash/webui/telemetry_extension_ui/mojom" ]
-  }
 }
 
 # This is needed as a dependency for api_guard_delegate_unittest.cc in
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function_browsertest.cc b/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function_browsertest.cc
index d147e91..fb1a152 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function_browsertest.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function_browsertest.cc
@@ -29,6 +29,13 @@
 #include "components/user_manager/user_manager.h"
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+#include "chromeos/crosapi/mojom/crosapi.mojom.h"
+#include "chromeos/crosapi/mojom/diagnostics_service.mojom.h"
+#include "chromeos/startup/browser_init_params.h"
+#include "components/policy/core/common/policy_loader_lacros.h"
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
 namespace chromeos {
 
 namespace {
@@ -425,6 +432,16 @@
   }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // Returns whether the Diagnostics interface is available. It may
+  // not be available on earlier versions of ash-chrome.
+  bool IsServiceAvailable() const {
+    chromeos::LacrosService* lacros_service = chromeos::LacrosService::Get();
+    return lacros_service &&
+           lacros_service->IsAvailable<crosapi::mojom::DiagnosticsService>();
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   GURL GetPwaGURL() const { return https_server_.GetURL("/ssl/google.html"); }
 
   // BaseTelemetryExtensionBrowserTest:
@@ -444,6 +461,19 @@
 // TODO(b/219514064): Make an equivalent test for Lacros.
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionApiGuardRealDelegateBrowserTest,
                        CanAccessRunBatteryCapacityRoutine) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // We can't run this test if Ash doesn't support the crosapi
+  // interface.
+  if (!IsServiceAvailable()) {
+    return;
+  }
+
+  // Setup the device ownership for Lacros
+  auto params = crosapi::mojom::BrowserInitParams::New();
+  params->is_current_user_device_owner = true;
+  chromeos::BrowserInitParams::SetInitParamsForTests(std::move(params));
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   // Add a new user and make it owner.
   auto* const user_manager = GetFakeUserManager();
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api.cc b/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api.cc
index c89992d..9efa00d 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api.cc
@@ -10,7 +10,7 @@
 
 #include "base/bind.h"
 #include "base/values.h"
-#include "chrome/browser/ash/telemetry_extension/diagnostics_service_ash.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_converters.h"
 #include "chrome/browser/chromeos/extensions/telemetry/api/remote_diagnostics_service_strategy.h"
 #include "chrome/common/chromeos/extensions/api/diagnostics.h"
@@ -28,9 +28,16 @@
 
 mojo::Remote<crosapi::mojom::DiagnosticsService>&
 DiagnosticsApiFunctionBase::GetRemoteService() {
+  DCHECK(remote_diagnostics_service_strategy_);
   return remote_diagnostics_service_strategy_->GetRemoteService();
 }
 
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+bool DiagnosticsApiFunctionBase::IsCrosApiAvailable() {
+  return remote_diagnostics_service_strategy_ != nullptr;
+}
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
 // OsDiagnosticsGetAvailableRoutinesFunction -----------------------------------
 
 OsDiagnosticsGetAvailableRoutinesFunction::
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api.h b/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api.h
index 1cf6140..e5cf0f91 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api.h
+++ b/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api.h
@@ -7,7 +7,7 @@
 
 #include <memory>
 
-#include "chrome/browser/ash/telemetry_extension/diagnostics_service_ash.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function.h"
 #include "chrome/browser/chromeos/extensions/telemetry/api/remote_diagnostics_service_strategy.h"
 #include "chromeos/crosapi/mojom/diagnostics_service.mojom.h"
@@ -31,6 +31,10 @@
 
   mojo::Remote<crosapi::mojom::DiagnosticsService>& GetRemoteService();
 
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  bool IsCrosApiAvailable() override;
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
  private:
   std::unique_ptr<RemoteDiagnosticsServiceStrategy>
       remote_diagnostics_service_strategy_;
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_browsertest.cc b/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_browsertest.cc
index 69485a0..14317bd 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_browsertest.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_browsertest.cc
@@ -3,24 +3,37 @@
 // found in the LICENSE file.
 
 #include <memory>
+#include <string>
 #include <utility>
 
 #include "base/values.h"
-#include "chrome/browser/ash/telemetry_extension/diagnostics_service_ash.h"
+#include "build/chromeos_buildflags.h"
 #include "chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.h"
 #include "chrome/browser/chromeos/extensions/telemetry/api/fake_diagnostics_service.h"
-#include "chrome/browser/chromeos/extensions/telemetry/api/fake_diagnostics_service_factory.h"
 #include "content/public/test/browser_test.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "chrome/browser/ash/telemetry_extension/diagnostics_service_ash.h"
+#include "chrome/browser/chromeos/extensions/telemetry/api/fake_diagnostics_service_factory.h"
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+#include "chromeos/crosapi/mojom/diagnostics_service.mojom.h"
+#include "chromeos/lacros/lacros_service.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
 namespace chromeos {
 
 class TelemetryExtensionDiagnosticsApiBrowserTest
     : public BaseTelemetryExtensionBrowserTest {
  public:
   TelemetryExtensionDiagnosticsApiBrowserTest() {
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     ash::DiagnosticsServiceAsh::Factory::SetForTesting(
         &fake_diagnostics_service_factory_);
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   }
 
   ~TelemetryExtensionDiagnosticsApiBrowserTest() override = default;
@@ -31,17 +44,265 @@
       const TelemetryExtensionDiagnosticsApiBrowserTest&) = delete;
 
  protected:
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // Returns whether the Diagnostics interface is available. It may
+  // not be available on earlier versions of ash-chrome.
+  bool IsServiceAvailable() const {
+    chromeos::LacrosService* lacros_service = chromeos::LacrosService::Get();
+    return lacros_service &&
+           lacros_service->IsAvailable<crosapi::mojom::DiagnosticsService>();
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   void SetServiceForTesting(
       std::unique_ptr<FakeDiagnosticsService> fake_diagnostics_service_impl) {
+#if BUILDFLAG(IS_CHROMEOS_ASH)
     fake_diagnostics_service_factory_.SetCreateInstanceResponse(
         std::move(fake_diagnostics_service_impl));
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+    // Replace the production DiagnosticsService with a fake for testing.
+    mojo::Remote<crosapi::mojom::DiagnosticsService>& remote =
+        chromeos::LacrosService::Get()
+            ->GetRemote<crosapi::mojom::DiagnosticsService>();
+    DCHECK(remote);
+    remote.reset();
+    fake_diagnostics_service_impl->BindPendingReceiver(
+        remote.BindNewPipeAndPassReceiver());
+    fake_diagnostics_service_impl_ = std::move(fake_diagnostics_service_impl);
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
   }
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   FakeDiagnosticsServiceFactory fake_diagnostics_service_factory_;
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  std::unique_ptr<FakeDiagnosticsService> fake_diagnostics_service_impl_;
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
 };
 
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
+                       LacrosServiceNotAvailableError) {
+  if (IsServiceAvailable()) {
+    return;
+  }
+
+  std::string service_worker = R"(
+    const tests = [
+      // Diagnostics APIs.
+      async function getAvailableRoutines() {
+        await chrome.test.assertPromiseRejects(
+            chrome.os.diagnostics.getAvailableRoutines(),
+            'Error: API chrome.os.diagnostics.getAvailableRoutines failed. ' +
+            'Not supported by ash browser'
+        );
+        chrome.test.succeed();
+      },
+      async function getRoutineUpdate() {
+        await chrome.test.assertPromiseRejects(
+            chrome.os.diagnostics.getRoutineUpdate(
+              {
+                id: 12345,
+                command: 'status'
+              }
+            ),
+            'Error: API chrome.os.diagnostics.getRoutineUpdate failed. ' +
+            'Not supported by ash browser'
+        );
+        chrome.test.succeed();
+      },
+      async function runAcPowerRoutine() {
+        await chrome.test.assertPromiseRejects(
+            chrome.os.diagnostics.runAcPowerRoutine(
+              {
+                expected_status: 'connected',
+                expected_power_type: 'ac_power'
+              }
+            ),
+            'Error: API chrome.os.diagnostics.runAcPowerRoutine failed. ' +
+            'Not supported by ash browser'
+        );
+        chrome.test.succeed();
+      },
+      async function runBatteryCapacityRoutine() {
+        await chrome.test.assertPromiseRejects(
+            chrome.os.diagnostics.runBatteryCapacityRoutine(),
+            'Error: API chrome.os.diagnostics.runBatteryCapacityRoutine ' +
+            'failed. Not supported by ash browser'
+        );
+        chrome.test.succeed();
+      },
+      async function runBatteryChargeRoutine() {
+        await chrome.test.assertPromiseRejects(
+            chrome.os.diagnostics.runBatteryChargeRoutine(
+              {
+                length_seconds: 1000,
+                minimum_charge_percent_required: 1
+              }
+            ),
+            'Error: API chrome.os.diagnostics.runBatteryChargeRoutine ' +
+            'failed. Not supported by ash browser'
+        );
+        chrome.test.succeed();
+      },
+      async function runBatteryDischargeRoutine() {
+        await chrome.test.assertPromiseRejects(
+            chrome.os.diagnostics.runBatteryDischargeRoutine(
+              {
+                length_seconds: 10,
+                maximum_discharge_percent_allowed: 15
+              }
+            ),
+            'Error: API chrome.os.diagnostics.runBatteryDischargeRoutine ' +
+            'failed. Not supported by ash browser'
+        );
+        chrome.test.succeed();
+      },
+      async function runBatteryHealthRoutine() {
+        await chrome.test.assertPromiseRejects(
+            chrome.os.diagnostics.runBatteryHealthRoutine(),
+            'Error: API chrome.os.diagnostics.runBatteryHealthRoutine ' +
+            'failed. Not supported by ash browser'
+        );
+        chrome.test.succeed();
+      },
+      async function runCpuCacheRoutine() {
+        await chrome.test.assertPromiseRejects(
+            chrome.os.diagnostics.runCpuCacheRoutine(
+              {
+                length_seconds: 120
+              }
+            ),
+            'Error: API chrome.os.diagnostics.runCpuCacheRoutine failed. ' +
+            'Not supported by ash browser'
+        );
+        chrome.test.succeed();
+      },
+      async function runCpuFloatingPointAccuracyRoutine() {
+        await chrome.test.assertPromiseRejects(
+            chrome.os.diagnostics.runCpuFloatingPointAccuracyRoutine(
+              {
+                length_seconds: 120
+              }
+            ),
+            'Error: API chrome.os.diagnostics.' +
+            'runCpuFloatingPointAccuracyRoutine failed. ' +
+            'Not supported by ash browser'
+        );
+        chrome.test.succeed();
+      },
+      async function runCpuPrimeSearchRoutine() {
+        await chrome.test.assertPromiseRejects(
+            chrome.os.diagnostics.runCpuPrimeSearchRoutine(
+              {
+                length_seconds: 120
+              }
+            ),
+            'Error: API chrome.os.diagnostics.runCpuPrimeSearchRoutine ' +
+            'failed. Not supported by ash browser'
+        );
+        chrome.test.succeed();
+      },
+      async function runCpuStressRoutine() {
+        await chrome.test.assertPromiseRejects(
+            chrome.os.diagnostics.runCpuStressRoutine(
+              {
+                length_seconds: 120
+              }
+            ),
+            'Error: API chrome.os.diagnostics.runCpuStressRoutine failed. ' +
+            'Not supported by ash browser'
+        );
+        chrome.test.succeed();
+      },
+      async function runDiskReadRoutine() {
+        await chrome.test.assertPromiseRejects(
+            chrome.os.diagnostics.runDiskReadRoutine(
+              {
+                type: 'random',
+                length_seconds: 60,
+                file_size_mb: 200
+              }
+            ),
+            'Error: API chrome.os.diagnostics.runDiskReadRoutine failed. ' +
+            'Not supported by ash browser'
+        );
+        chrome.test.succeed();
+      },
+      async function runLanConnectivityRoutine() {
+        await chrome.test.assertPromiseRejects(
+            chrome.os.diagnostics.runLanConnectivityRoutine(),
+            'Error: API chrome.os.diagnostics.runLanConnectivityRoutine ' +
+            'failed. Not supported by ash browser'
+        );
+        chrome.test.succeed();
+      },
+      async function runMemoryRoutine() {
+        await chrome.test.assertPromiseRejects(
+            chrome.os.diagnostics.runMemoryRoutine(),
+            'Error: API chrome.os.diagnostics.runMemoryRoutine failed. ' +
+            'Not supported by ash browser'
+        );
+        chrome.test.succeed();
+      },
+      async function runNvmeWearLevelRoutine() {
+        await chrome.test.assertPromiseRejects(
+            chrome.os.diagnostics.runNvmeWearLevelRoutine(
+              {
+                wear_level_threshold: 80
+              }
+            ),
+            'Error: API chrome.os.diagnostics.runNvmeWearLevelRoutine ' +
+            'failed. Not supported by ash browser'
+        );
+        chrome.test.succeed();
+      },
+      async function runSmartctlCheckRoutine() {
+        await chrome.test.assertPromiseRejects(
+            chrome.os.diagnostics.runSmartctlCheckRoutine(),
+            'Error: API chrome.os.diagnostics.runSmartctlCheckRoutine ' +
+            'failed. Not supported by ash browser'
+        );
+        chrome.test.succeed();
+      },
+    ];
+
+    chrome.test.runTests([
+      async function allAPIsTested() {
+        getTestNames = function(arr) {
+          return arr.map(item => item.name);
+        }
+        getMethods = function(obj) {
+          return Object.getOwnPropertyNames(obj).filter(
+            item => typeof obj[item] === 'function');
+        }
+        apiNames = [
+          ...getMethods(chrome.os.diagnostics)
+        ];
+        chrome.test.assertEq(getTestNames(tests), apiNames);
+        chrome.test.succeed();
+      },
+      ...tests
+    ]);
+  )";
+
+  CreateExtensionAndRunServiceWorker(service_worker);
+}
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
                        GetAvailableRoutinesSuccess) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // If Diagnostics interface is not available on this version of ash-chrome,
+  // this test suite will no-op.
+  if (!IsServiceAvailable()) {
+    return;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   {
     auto fake_service_impl = std::make_unique<FakeDiagnosticsService>();
     fake_service_impl->SetAvailableRoutines({
@@ -96,6 +357,14 @@
 
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
                        GetRoutineUpdateNonInteractiveSuccess) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // If Diagnostics interface is not available on this version of ash-chrome,
+  // this test suite will no-op.
+  if (!IsServiceAvailable()) {
+    return;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   // Configure FakeDiagnosticsService.
   {
     auto nonInteractiveRoutineUpdate =
@@ -156,6 +425,14 @@
 
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
                        GetRoutineUpdateInteractiveSuccess) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // If Diagnostics interface is not available on this version of ash-chrome,
+  // this test suite will no-op.
+  if (!IsServiceAvailable()) {
+    return;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   // Configure FakeDiagnosticsService.
   {
     auto interactiveRoutineUpdate =
@@ -216,6 +493,14 @@
 
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
                        RunAcPowerRoutineSuccess) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // If Diagnostics interface is not available on this version of ash-chrome,
+  // this test suite will no-op.
+  if (!IsServiceAvailable()) {
+    return;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   // Configure FakeDiagnosticsService.
   {
     auto expected_response =
@@ -263,6 +548,14 @@
 
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
                        RunBatteryCapacityRoutineSuccess) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // If Diagnostics interface is not available on this version of ash-chrome,
+  // this test suite will no-op.
+  if (!IsServiceAvailable()) {
+    return;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   // Configure FakeDiagnosticsService.
   {
     auto expected_response =
@@ -296,6 +589,14 @@
 
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
                        RunBatteryChargeRoutineSuccess) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // If Diagnostics interface is not available on this version of ash-chrome,
+  // this test suite will no-op.
+  if (!IsServiceAvailable()) {
+    return;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   // Configure FakeDiagnosticsService.
   {
     auto expected_response =
@@ -340,6 +641,14 @@
 
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
                        RunBatteryDischargeRoutineSuccess) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // If Diagnostics interface is not available on this version of ash-chrome,
+  // this test suite will no-op.
+  if (!IsServiceAvailable()) {
+    return;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   // Configure FakeDiagnosticsService.
   {
     auto expected_response =
@@ -384,6 +693,14 @@
 
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
                        RunBatteryHealthRoutineSuccess) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // If Diagnostics interface is not available on this version of ash-chrome,
+  // this test suite will no-op.
+  if (!IsServiceAvailable()) {
+    return;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   // Configure FakeDiagnosticsService.
   {
     auto expected_response =
@@ -417,6 +734,14 @@
 
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
                        RunCpuCacheRoutineSuccess) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // If Diagnostics interface is not available on this version of ash-chrome,
+  // this test suite will no-op.
+  if (!IsServiceAvailable()) {
+    return;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   // Configure FakeDiagnosticsService.
   {
     auto expected_response =
@@ -459,6 +784,14 @@
 
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
                        RunCpuFloatingPointAccuracyRoutineSuccess) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // If Diagnostics interface is not available on this version of ash-chrome,
+  // this test suite will no-op.
+  if (!IsServiceAvailable()) {
+    return;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   // Configure FakeDiagnosticsService.
   {
     auto expected_response =
@@ -501,6 +834,14 @@
 
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
                        RunCpuPrimeSearchRoutineSuccess) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // If Diagnostics interface is not available on this version of ash-chrome,
+  // this test suite will no-op.
+  if (!IsServiceAvailable()) {
+    return;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   // Configure FakeDiagnosticsService.
   {
     auto expected_response =
@@ -543,6 +884,14 @@
 
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
                        RunCpuStressRoutineSuccess) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // If Diagnostics interface is not available on this version of ash-chrome,
+  // this test suite will no-op.
+  if (!IsServiceAvailable()) {
+    return;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   // Configure FakeDiagnosticsService.
   {
     auto expected_response =
@@ -585,6 +934,14 @@
 
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
                        RunDiskReadRoutineSuccess) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // If Diagnostics interface is not available on this version of ash-chrome,
+  // this test suite will no-op.
+  if (!IsServiceAvailable()) {
+    return;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   // Configure FakeDiagnosticsService.
   {
     auto expected_response =
@@ -634,6 +991,14 @@
 
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
                        RunLanConnectivityRoutineSuccess) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // If Diagnostics interface is not available on this version of ash-chrome,
+  // this test suite will no-op.
+  if (!IsServiceAvailable()) {
+    return;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   // Configure FakeDiagnosticsService.
   {
     auto expected_response =
@@ -667,6 +1032,14 @@
 
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
                        RunMemoryRoutineSuccess) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // If Diagnostics interface is not available on this version of ash-chrome,
+  // this test suite will no-op.
+  if (!IsServiceAvailable()) {
+    return;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   // Configure FakeDiagnosticsService.
   {
     auto expected_response =
@@ -700,6 +1073,14 @@
 
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
                        RunNvmeWearLevelRoutineSuccess) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // If Diagnostics interface is not available on this version of ash-chrome,
+  // this test suite will no-op.
+  if (!IsServiceAvailable()) {
+    return;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   // Configure FakeDiagnosticsService.
   {
     auto expected_response =
@@ -742,6 +1123,14 @@
 
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
                        RunSmartctlCheckRoutineSuccess) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // If Diagnostics interface is not available on this version of ash-chrome,
+  // this test suite will no-op.
+  if (!IsServiceAvailable()) {
+    return;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   // Configure FakeDiagnosticsService.
   {
     auto expected_response =
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_unittest.cc b/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_unittest.cc
index 39c5946..ff22d87 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_unittest.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_reporting_manager_unittest.cc
@@ -27,7 +27,9 @@
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
+#include "chromeos/crosapi/mojom/crosapi.mojom.h"
 #include "chromeos/lacros/lacros_service.h"
+#include "chromeos/startup/browser_init_params.h"
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
 
 using ::testing::_;
@@ -85,6 +87,24 @@
   }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+
+  void SetSessionType(crosapi::mojom::SessionType session_type) {
+    auto init_params = crosapi::mojom::BrowserInitParams::New();
+    init_params->session_type = session_type;
+    chromeos::BrowserInitParams::SetInitParamsForTests(std::move(init_params));
+  }
+
+  void ReportEventAndCheckUser(DlpPolicyEvent_UserType dlp_user_type,
+                               unsigned int event_number) {
+    manager_.ReportEvent(kCompanyPattern,
+                         DlpRulesManager::Restriction::kPrinting,
+                         DlpRulesManager::Level::kBlock);
+    ASSERT_EQ(events_.size(), event_number + 1);
+    EXPECT_EQ(events_[event_number].user_type(), dlp_user_type);
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
   content::BrowserTaskEnvironment task_environment_;
   DlpReportingManager manager_;
   std::vector<DlpPolicyEvent> events_;
@@ -166,7 +186,6 @@
       DlpRulesManager::Restriction::kUnknownRestriction, 1);
 }
 
-// TODO(crbug.com/1262948): Enable and modify for lacros.
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 TEST_F(DlpReportingManagerTest, UserType) {
   auto* user_manager = new ash::FakeChromeUserManager();
@@ -218,6 +237,30 @@
 }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+TEST_F(DlpReportingManagerTest, UserType) {
+  SetSessionType(crosapi::mojom::SessionType::kRegularSession);
+  ReportEventAndCheckUser(DlpPolicyEvent_UserType_REGULAR, 0u);
+
+  SetSessionType(crosapi::mojom::SessionType::kPublicSession);
+  ReportEventAndCheckUser(DlpPolicyEvent_UserType_MANAGED_GUEST, 1u);
+
+  SetSessionType(crosapi::mojom::SessionType::kAppKioskSession);
+  ReportEventAndCheckUser(DlpPolicyEvent_UserType_KIOSK, 2u);
+
+  SetSessionType(crosapi::mojom::SessionType::kWebKioskSession);
+  ReportEventAndCheckUser(DlpPolicyEvent_UserType_KIOSK, 3u);
+
+  SetSessionType(crosapi::mojom::SessionType::kGuestSession);
+  ReportEventAndCheckUser(DlpPolicyEvent_UserType_UNDEFINED_USER_TYPE, 4u);
+
+  SetSessionType(crosapi::mojom::SessionType::kChildSession);
+  ReportEventAndCheckUser(DlpPolicyEvent_UserType_UNDEFINED_USER_TYPE, 5u);
+
+  EXPECT_EQ(manager_.events_reported(), 6u);
+}
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
 TEST_F(DlpReportingManagerTest, CreateEventWithUnknownRestriction) {
   DlpPolicyEvent event = policy::CreateDlpPolicyEvent(
       kCompanyPattern, DlpRulesManager::Restriction::kUnknownRestriction,
diff --git a/chrome/browser/device_reauth/android/biometric_authenticator_android.cc b/chrome/browser/device_reauth/android/biometric_authenticator_android.cc
index d8a4c99..35d7f8f3 100644
--- a/chrome/browser/device_reauth/android/biometric_authenticator_android.cc
+++ b/chrome/browser/device_reauth/android/biometric_authenticator_android.cc
@@ -55,7 +55,9 @@
   }
 }
 
-bool isPasswordManagerRequester(
+// Checks whether authentication request was made by the password manager on
+// Android.
+bool isAndroidPasswordManagerRequester(
     const device_reauth::BiometricAuthRequester& requester) {
   switch (requester) {
     case device_reauth::BiometricAuthRequester::kTouchToFill:
@@ -66,33 +68,28 @@
     case device_reauth::BiometricAuthRequester::kPasswordCheckAutoPwdChange:
       return true;
     case device_reauth::BiometricAuthRequester::kIncognitoReauthPage:
+    // kPasswordsInSettings flag is used only for desktop.
+    case device_reauth::BiometricAuthRequester::kPasswordsInSettings:
       return false;
   }
 }
 
 void LogAuthResult(const device_reauth::BiometricAuthRequester& requester,
                    const BiometricAuthFinalResult& result) {
-  if (isPasswordManagerRequester(requester)) {
+  if (isAndroidPasswordManagerRequester(requester)) {
     base::UmaHistogramEnumeration(
         "PasswordManager.BiometricAuthPwdFill.AuthResult", result);
   }
 }
 
 void LogAuthRequester(const device_reauth::BiometricAuthRequester& requester) {
-  // TODO(crbug.com/1263397): The
-  // "PasswordManager.BiometricAuthPwdFill.AuthRequester" should be removed once
-  // the "Android.BiometricAuth.AuthRequester" is saturated and adopted.
-  if (isPasswordManagerRequester(requester)) {
-    base::UmaHistogramEnumeration(
-        "PasswordManager.BiometricAuthPwdFill.AuthRequester", requester);
-  }
   base::UmaHistogramEnumeration("Android.BiometricAuth.AuthRequester",
                                 requester);
 }
 
 void LogCanAuthenticate(const device_reauth::BiometricAuthRequester& requester,
                         const BiometricsAvailability& availability) {
-  if (isPasswordManagerRequester(requester)) {
+  if (isAndroidPasswordManagerRequester(requester)) {
     base::UmaHistogramEnumeration(
         "PasswordManager.BiometricAuthPwdFill.CanAuthenticate", availability);
   }
diff --git a/chrome/browser/device_reauth/android/biometric_authenticator_android_unittest.cc b/chrome/browser/device_reauth/android/biometric_authenticator_android_unittest.cc
index 4bc19a65..ca7fe0d9 100644
--- a/chrome/browser/device_reauth/android/biometric_authenticator_android_unittest.cc
+++ b/chrome/browser/device_reauth/android/biometric_authenticator_android_unittest.cc
@@ -109,9 +109,6 @@
   authenticator()->Authenticate(BiometricAuthRequester::kAllPasswordsList,
                                 base::DoNothing(),
                                 /*use_last_valid_auth=*/true);
-  histogram_tester.ExpectUniqueSample(
-      "PasswordManager.BiometricAuthPwdFill.AuthRequester",
-      BiometricAuthRequester::kAllPasswordsList, 1);
 
   histogram_tester.ExpectUniqueSample("Android.BiometricAuth.AuthRequester",
                                       BiometricAuthRequester::kAllPasswordsList,
diff --git a/chrome/browser/download/download_item_model_unittest.cc b/chrome/browser/download/download_item_model_unittest.cc
index e2dd00c..d30021f42 100644
--- a/chrome/browser/download/download_item_model_unittest.cc
+++ b/chrome/browser/download/download_item_model_unittest.cc
@@ -21,16 +21,22 @@
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "chrome/browser/download/download_commands.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/testing_profile.h"
+#include "chrome/test/base/testing_profile_manager.h"
 #include "components/download/public/common/download_danger_type.h"
 #include "components/download/public/common/mock_download_item.h"
 #include "components/enterprise/common/download_item_reroute_info.h"
 #include "components/safe_browsing/core/common/features.h"
 #include "components/vector_icons/vector_icons.h"
+#include "content/public/browser/download_item_utils.h"
+#include "content/public/test/browser_task_environment.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/text/bytes_formatting.h"
 
 #if !BUILDFLAG(IS_ANDROID)
+#include "chrome/browser/enterprise/connectors/connectors_service.h"
 #include "ui/views/vector_icons.h"
 #endif
 
@@ -97,10 +103,22 @@
 class DownloadItemModelTest : public testing::Test {
  public:
   DownloadItemModelTest()
-      : model_(&item_) {}
+      : model_(&item_),
+        testing_profile_manager_(TestingBrowserProcess::GetGlobal()) {
+    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+#if !BUILDFLAG(IS_ANDROID)
+    scoped_feature_list_.InitWithFeatures(
+        {}, {enterprise_connectors::kEnterpriseConnectorsEnabled});
+#endif
+  }
 
   ~DownloadItemModelTest() override {}
 
+  void SetUp() override {
+    ASSERT_TRUE(testing_profile_manager_.SetUp());
+    profile_ = testing_profile_manager_.CreateTestingProfile("testing_profile");
+  }
+
  protected:
   // Sets up defaults for the download item and sets |model_| to a new
   // DownloadItemModel that uses the mock download item.
@@ -132,6 +150,8 @@
             Return(download::DownloadItem::MixedContentStatus::SAFE));
     ON_CALL(item(), GetDangerType())
         .WillByDefault(Return(download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS));
+    content::DownloadItemUtils::AttachInfoForTesting(&(item()), profile_,
+                                                     nullptr);
   }
 
   void SetupInterruptedDownloadItem(download::DownloadInterruptReason reason) {
@@ -170,10 +190,16 @@
   }
 #endif
 
+  content::BrowserTaskEnvironment task_environment_;
+
  private:
   NiceMock<download::MockDownloadItem> item_;
   DownloadItemModel model_;
   base::SimpleTestClock clock_;
+  TestingProfileManager testing_profile_manager_;
+  raw_ptr<TestingProfile> profile_;
+
+  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 TEST_F(DownloadItemModelTest, InterruptedStatus) {
@@ -713,7 +739,135 @@
 }
 
 #if !BUILDFLAG(IS_ANDROID)
-TEST_F(DownloadItemModelTest, InterruptedBubbleUIInfo) {
+
+TEST_F(DownloadItemModelTest, DangerousWarningBubbleUIInfo_V2On) {
+  SetupCompletedDownloadItem(base::Hours(1));
+  const struct DangerTypeTestCase {
+    download::DownloadDangerType danger_type;
+    bool has_checkbox;
+    absl::optional<DownloadCommands::Command> primary_button_command;
+    std::vector<DownloadCommands::Command> subpage_button_commands;
+  } kDangerTypeTestCases[] = {
+      {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
+       false,
+       DownloadCommands::Command::KEEP,
+       {DownloadCommands::Command::DISCARD, DownloadCommands::Command::KEEP}},
+      {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT,
+       false,
+       DownloadCommands::Command::DISCARD,
+       {DownloadCommands::Command::DISCARD}},
+      {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST,
+       false,
+       DownloadCommands::Command::DISCARD,
+       {DownloadCommands::Command::DISCARD}},
+      {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_ACCOUNT_COMPROMISE,
+       false,
+       DownloadCommands::Command::DISCARD,
+       {DownloadCommands::Command::DISCARD}},
+      {download::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED,
+       false,
+       DownloadCommands::Command::DISCARD,
+       {DownloadCommands::Command::DISCARD}},
+      {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
+       false,
+       DownloadCommands::Command::DISCARD,
+       {DownloadCommands::Command::DISCARD}},
+      {download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_WARNING,
+       false,
+       DownloadCommands::Command::DISCARD,
+       {DownloadCommands::Command::DISCARD, DownloadCommands::Command::KEEP}},
+      {download::DOWNLOAD_DANGER_TYPE_PROMPT_FOR_SCANNING,
+       false,
+       DownloadCommands::Command::DEEP_SCAN,
+       {DownloadCommands::Command::DEEP_SCAN,
+        DownloadCommands::Command::BYPASS_DEEP_SCANNING}},
+      {download::DOWNLOAD_DANGER_TYPE_ASYNC_SCANNING,
+       false,
+       DownloadCommands::Command::BYPASS_DEEP_SCANNING,
+       {}},
+  };
+  for (const auto& test_case : kDangerTypeTestCases) {
+    SetupDownloadItemDefaults();
+    ON_CALL(item(), GetDangerType())
+        .WillByDefault(Return(test_case.danger_type));
+    DownloadUIModel::BubbleUIInfo bubble_ui_info =
+        model().GetBubbleUIInfo(/*is_download_bubble_v2=*/true);
+    EXPECT_EQ(bubble_ui_info.has_checkbox, test_case.has_checkbox);
+    EXPECT_EQ(bubble_ui_info.primary_button_command,
+              test_case.primary_button_command);
+    std::vector<DownloadCommands::Command> subpage_commands;
+    for (auto button : bubble_ui_info.subpage_buttons) {
+      subpage_commands.push_back(button.command);
+    }
+    EXPECT_EQ(subpage_commands, test_case.subpage_button_commands);
+  }
+}
+
+TEST_F(DownloadItemModelTest, DangerousWarningBubbleUIInfo_V2Off) {
+  SetupCompletedDownloadItem(base::Hours(1));
+  SetIsBubbleV2Enabled(false);
+  const struct DangerTypeTestCase {
+    download::DownloadDangerType danger_type;
+    bool has_checkbox;
+    absl::optional<DownloadCommands::Command> primary_button_command;
+    std::vector<DownloadCommands::Command> subpage_button_commands;
+  } kDangerTypeTestCases[] = {
+      {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
+       false,
+       DownloadCommands::Command::KEEP,
+       {DownloadCommands::Command::DISCARD, DownloadCommands::Command::KEEP}},
+      {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT,
+       true,
+       DownloadCommands::Command::DISCARD,
+       {DownloadCommands::Command::DISCARD, DownloadCommands::Command::KEEP}},
+      {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST,
+       true,
+       DownloadCommands::Command::DISCARD,
+       {DownloadCommands::Command::DISCARD, DownloadCommands::Command::KEEP}},
+      {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_ACCOUNT_COMPROMISE,
+       true,
+       DownloadCommands::Command::DISCARD,
+       {DownloadCommands::Command::DISCARD, DownloadCommands::Command::KEEP}},
+      {download::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED,
+       true,
+       DownloadCommands::Command::DISCARD,
+       {DownloadCommands::Command::DISCARD, DownloadCommands::Command::KEEP}},
+      {download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
+       true,
+       DownloadCommands::Command::DISCARD,
+       {DownloadCommands::Command::DISCARD, DownloadCommands::Command::KEEP}},
+      {download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_WARNING,
+       false,
+       DownloadCommands::Command::DISCARD,
+       {DownloadCommands::Command::DISCARD, DownloadCommands::Command::KEEP}},
+      {download::DOWNLOAD_DANGER_TYPE_PROMPT_FOR_SCANNING,
+       false,
+       DownloadCommands::Command::DEEP_SCAN,
+       {DownloadCommands::Command::DEEP_SCAN,
+        DownloadCommands::Command::BYPASS_DEEP_SCANNING}},
+      {download::DOWNLOAD_DANGER_TYPE_ASYNC_SCANNING,
+       false,
+       DownloadCommands::Command::BYPASS_DEEP_SCANNING,
+       {}},
+  };
+  for (const auto& test_case : kDangerTypeTestCases) {
+    SetupDownloadItemDefaults();
+    ON_CALL(item(), GetDangerType())
+        .WillByDefault(Return(test_case.danger_type));
+    DownloadUIModel::BubbleUIInfo bubble_ui_info =
+        model().GetBubbleUIInfo(/*is_download_bubble_v2=*/false);
+    EXPECT_EQ(bubble_ui_info.has_checkbox, test_case.has_checkbox);
+    EXPECT_EQ(bubble_ui_info.primary_button_command,
+              test_case.primary_button_command);
+    std::vector<DownloadCommands::Command> subpage_commands;
+    for (auto button : bubble_ui_info.subpage_buttons) {
+      subpage_commands.push_back(button.command);
+    }
+    EXPECT_EQ(subpage_commands, test_case.subpage_button_commands);
+  }
+}
+
+TEST_F(DownloadItemModelTest, InterruptedBubbleUIInfo_V2On) {
   std::vector<download::DownloadInterruptReason> no_retry_interrupt_reasons = {
       download::DOWNLOAD_INTERRUPT_REASON_FILE_TOO_LARGE,
       download::DOWNLOAD_INTERRUPT_REASON_FILE_VIRUS_INFECTED,
@@ -787,7 +941,8 @@
       EXPECT_CALL(item(), CanResume())
           .WillRepeatedly(Return(test_case.can_resume));
 
-      DownloadUIModel::BubbleUIInfo bubble_ui_info = model().GetBubbleUIInfo();
+      DownloadUIModel::BubbleUIInfo bubble_ui_info =
+          model().GetBubbleUIInfo(/*is_download_bubble_v2=*/true);
       EXPECT_EQ(test_case.expected_warning_summary,
                 base::UTF16ToUTF8(bubble_ui_info.warning_summary));
       EXPECT_EQ(test_case.expected_icon_model_override,
@@ -800,7 +955,7 @@
   }
 }
 
-TEST_F(DownloadItemModelTest, InterruptedBubbleUIInfo_BubbleV2Off) {
+TEST_F(DownloadItemModelTest, InterruptedBubbleUIInfo_V2Off) {
   const struct TestCase {
     std::vector<download::DownloadInterruptReason> interrupt_reasons;
 
@@ -837,7 +992,8 @@
   for (const auto& test_case : kTestCases) {
     for (const auto& interrupt_reason : test_case.interrupt_reasons) {
       SetupInterruptedDownloadItem(interrupt_reason);
-      DownloadUIModel::BubbleUIInfo bubble_ui_info = model().GetBubbleUIInfo();
+      DownloadUIModel::BubbleUIInfo bubble_ui_info =
+          model().GetBubbleUIInfo(/*is_download_bubble_v2=*/false);
       EXPECT_EQ(test_case.expected_warning_summary,
                 base::UTF16ToUTF8(bubble_ui_info.warning_summary));
       EXPECT_EQ(test_case.expected_icon_model_override,
diff --git a/chrome/browser/download/download_ui_model.cc b/chrome/browser/download/download_ui_model.cc
index b4826db..8601272 100644
--- a/chrome/browser/download/download_ui_model.cc
+++ b/chrome/browser/download/download_ui_model.cc
@@ -902,7 +902,8 @@
 }
 
 DownloadUIModel::BubbleUIInfo
-DownloadUIModel::GetBubbleUIInfoForInProgressOrComplete() const {
+DownloadUIModel::GetBubbleUIInfoForInProgressOrComplete(
+    bool is_download_bubble_v2) const {
   switch (GetMixedContentStatus()) {
     case download::DownloadItem::MixedContentStatus::BLOCK:
     case download::DownloadItem::MixedContentStatus::WARN:
@@ -912,12 +913,12 @@
           .AddIconAndColor(vector_icons::kNotSecureWarningIcon,
                            ui::kColorAlertMediumSeverity)
           .AddSubpageButton(
-              l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE),
-              DownloadCommands::Command::KEEP, /*is_prominent=*/false)
-          .AddSubpageButton(
               l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_DELETE),
               DownloadCommands::Command::DISCARD,
-              /*is_prominent=*/true);
+              /*is_prominent=*/true)
+          .AddSubpageButton(
+              l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE),
+              DownloadCommands::Command::KEEP, /*is_prominent=*/false);
     case download::DownloadItem::MixedContentStatus::UNKNOWN:
     case download::DownloadItem::MixedContentStatus::SAFE:
     case download::DownloadItem::MixedContentStatus::VALIDATED:
@@ -947,6 +948,7 @@
     }
   }
 
+  DownloadUIModel::BubbleUIInfo ui_info;
   switch (GetDangerType()) {
     case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE:
       if (IsExtensionDownload()) {
@@ -957,13 +959,13 @@
                            IDS_EXTENSION_WEB_STORE_TITLE)))
             .AddIconAndColor(views::kInfoIcon, ui::kColorAlertMediumSeverity)
             .AddSubpageButton(
-                l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE),
-                DownloadCommands::Command::KEEP,
-                /*is_prominent=*/false)
-            .AddSubpageButton(
                 l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_DELETE),
                 DownloadCommands::Command::DISCARD,
-                /*is_prominent=*/true);
+                /*is_prominent=*/true)
+            .AddSubpageButton(
+                l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE),
+                DownloadCommands::Command::KEEP,
+                /*is_prominent=*/false);
       } else {
         return DownloadUIModel::BubbleUIInfo(
                    l10n_util::GetStringUTF16(
@@ -971,67 +973,81 @@
             .AddIconAndColor(views::kInfoIcon, ui::kColorSecondaryForeground)
             .AddPrimaryButton(DownloadCommands::Command::KEEP)
             .AddSubpageButton(
-                l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE),
-                DownloadCommands::Command::KEEP,
-                /*is_prominent=*/false)
-            .AddSubpageButton(
                 l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_DELETE),
                 DownloadCommands::Command::DISCARD,
+                /*is_prominent=*/false)
+            .AddSubpageButton(
+                l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE),
+                DownloadCommands::Command::KEEP,
                 /*is_prominent=*/false);
       }
     case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT:
     case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST:
     case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_ACCOUNT_COMPROMISE:
-      return DownloadUIModel::BubbleUIInfo(
-                 l10n_util::GetStringUTF16(
-                     IDS_DOWNLOAD_BUBBLE_MALICIOUS_URL_BLOCKED))
-          .AddIconAndColor(vector_icons::kNotSecureWarningIcon,
-                           ui::kColorAlertHighSeverity)
-          .AddPrimaryButton(DownloadCommands::Command::DISCARD)
-          .AddCheckbox(
-              l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CHECKBOX_BYPASS))
-          .AddSubpageButton(
-              l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE),
-              DownloadCommands::Command::KEEP,
-              /*is_prominent=*/false)
-          .AddSubpageButton(
-              l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_DELETE),
-              DownloadCommands::Command::DISCARD,
-              /*is_prominent=*/true);
+      ui_info = DownloadUIModel::BubbleUIInfo(
+                    l10n_util::GetStringUTF16(
+                        IDS_DOWNLOAD_BUBBLE_MALICIOUS_URL_BLOCKED))
+                    .AddIconAndColor(vector_icons::kNotSecureWarningIcon,
+                                     ui::kColorAlertHighSeverity)
+                    .AddPrimaryButton(DownloadCommands::Command::DISCARD)
+                    .AddSubpageButton(
+                        l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_DELETE),
+                        DownloadCommands::Command::DISCARD,
+                        /*is_prominent=*/true);
+      if (!is_download_bubble_v2) {
+        ui_info
+            .AddCheckbox(
+                l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CHECKBOX_BYPASS))
+            .AddSubpageButton(
+                l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE),
+                DownloadCommands::Command::KEEP,
+                /*is_prominent=*/false);
+      }
+      return ui_info;
+
     case download::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED:
-      return DownloadUIModel::BubbleUIInfo(
-                 l10n_util::GetStringUTF16(
-                     IDS_DOWNLOAD_BUBBLE_MALICIOUS_URL_BLOCKED))
-          .AddIconAndColor(vector_icons::kNotSecureWarningIcon,
-                           ui::kColorAlertMediumSeverity)
-          .AddPrimaryButton(DownloadCommands::Command::DISCARD)
-          .AddCheckbox(
-              l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CHECKBOX_BYPASS))
-          .AddSubpageButton(
-              l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE),
-              DownloadCommands::Command::KEEP,
-              /*is_prominent=*/false)
-          .AddSubpageButton(
-              l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_DELETE),
-              DownloadCommands::Command::DISCARD,
-              /*is_prominent=*/true);
+      ui_info = DownloadUIModel::BubbleUIInfo(
+                    l10n_util::GetStringUTF16(
+                        IDS_DOWNLOAD_BUBBLE_MALICIOUS_URL_BLOCKED))
+                    .AddIconAndColor(vector_icons::kNotSecureWarningIcon,
+                                     ui::kColorAlertMediumSeverity)
+                    .AddPrimaryButton(DownloadCommands::Command::DISCARD)
+                    .AddSubpageButton(
+                        l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_DELETE),
+                        DownloadCommands::Command::DISCARD,
+                        /*is_prominent=*/true);
+      if (!is_download_bubble_v2) {
+        ui_info
+            .AddCheckbox(
+                l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CHECKBOX_BYPASS))
+            .AddSubpageButton(
+                l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE),
+                DownloadCommands::Command::KEEP,
+                /*is_prominent=*/false);
+      }
+      return ui_info;
+
     case download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL:
-      return DownloadUIModel::BubbleUIInfo(
-                 l10n_util::GetStringUTF16(
-                     IDS_DOWNLOAD_BUBBLE_SUBPAGE_SUMMARY_MALWARE))
-          .AddIconAndColor(vector_icons::kNotSecureWarningIcon,
-                           ui::kColorAlertHighSeverity)
-          .AddPrimaryButton(DownloadCommands::Command::DISCARD)
-          .AddCheckbox(
-              l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CHECKBOX_BYPASS))
-          .AddSubpageButton(
-              l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE),
-              DownloadCommands::Command::KEEP,
-              /*is_prominent=*/false)
-          .AddSubpageButton(
-              l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_DELETE),
-              DownloadCommands::Command::DISCARD,
-              /*is_prominent=*/true);
+      ui_info = DownloadUIModel::BubbleUIInfo(
+                    l10n_util::GetStringUTF16(
+                        IDS_DOWNLOAD_BUBBLE_SUBPAGE_SUMMARY_MALWARE))
+                    .AddIconAndColor(vector_icons::kNotSecureWarningIcon,
+                                     ui::kColorAlertHighSeverity)
+                    .AddPrimaryButton(DownloadCommands::Command::DISCARD)
+                    .AddSubpageButton(
+                        l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_DELETE),
+                        DownloadCommands::Command::DISCARD,
+                        /*is_prominent=*/true);
+      if (!is_download_bubble_v2) {
+        ui_info
+            .AddCheckbox(
+                l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CHECKBOX_BYPASS))
+            .AddSubpageButton(
+                l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE),
+                DownloadCommands::Command::KEEP,
+                /*is_prominent=*/false);
+      }
+      return ui_info;
     case download::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT: {
       bool request_ap_verdicts = false;
 #if BUILDFLAG(FULL_SAFE_BROWSING)
@@ -1047,13 +1063,13 @@
             .AddIconAndColor(vector_icons::kNotSecureWarningIcon,
                              ui::kColorAlertMediumSeverity)
             .AddSubpageButton(
-                l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE),
-                DownloadCommands::Command::KEEP,
-                /*is_prominent=*/false)
-            .AddSubpageButton(
                 l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_DELETE),
                 DownloadCommands::Command::DISCARD,
-                /*is_prominent=*/true);
+                /*is_prominent=*/true)
+            .AddSubpageButton(
+                l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE),
+                DownloadCommands::Command::KEEP,
+                /*is_prominent=*/false);
       } else {
         return DownloadUIModel::BubbleUIInfo(
                    l10n_util::GetStringUTF16(
@@ -1061,13 +1077,13 @@
             .AddIconAndColor(views::kInfoIcon, ui::kColorAlertMediumSeverity)
             .AddPrimaryButton(DownloadCommands::Command::DISCARD)
             .AddSubpageButton(
-                l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE),
-                DownloadCommands::Command::KEEP,
-                /*is_prominent=*/false)
-            .AddSubpageButton(
                 l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_DELETE),
                 DownloadCommands::Command::DISCARD,
-                /*is_prominent=*/true);
+                /*is_prominent=*/true)
+            .AddSubpageButton(
+                l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE),
+                DownloadCommands::Command::KEEP,
+                /*is_prominent=*/false);
       }
     }
     case download::DOWNLOAD_DANGER_TYPE_SENSITIVE_CONTENT_WARNING:
@@ -1077,13 +1093,13 @@
           .AddIconAndColor(views::kInfoIcon, ui::kColorAlertMediumSeverity)
           .AddPrimaryButton(DownloadCommands::Command::DISCARD)
           .AddSubpageButton(
-              l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE),
-              DownloadCommands::Command::KEEP,
-              /*is_prominent=*/false)
-          .AddSubpageButton(
               l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_DELETE),
               DownloadCommands::Command::DISCARD,
-              /*is_prominent=*/true);
+              /*is_prominent=*/true)
+          .AddSubpageButton(
+              l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_CONTINUE),
+              DownloadCommands::Command::KEEP,
+              /*is_prominent=*/false);
     case download::DOWNLOAD_DANGER_TYPE_PROMPT_FOR_SCANNING:
       return DownloadUIModel::BubbleUIInfo(
                  l10n_util::GetStringUTF16(
@@ -1091,12 +1107,12 @@
           .AddIconAndColor(vector_icons::kNotSecureWarningIcon,
                            ui::kColorAlertMediumSeverity)
           .AddPrimaryButton(DownloadCommands::Command::DEEP_SCAN)
-          .AddSubpageButton(l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_OPEN),
-                            DownloadCommands::Command::BYPASS_DEEP_SCANNING,
-                            /*is_prominent=*/false)
           .AddSubpageButton(l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_SCAN),
                             DownloadCommands::Command::DEEP_SCAN,
-                            /*is_prominent=*/true);
+                            /*is_prominent=*/true)
+          .AddSubpageButton(l10n_util::GetStringUTF16(IDS_DOWNLOAD_BUBBLE_OPEN),
+                            DownloadCommands::Command::BYPASS_DEEP_SCANNING,
+                            /*is_prominent=*/false);
     case download::DOWNLOAD_DANGER_TYPE_ASYNC_SCANNING: {
       BubbleUIInfo bubble_ui_info =
           DownloadUIModel::BubbleUIInfo(/*has_progress_bar=*/true)
@@ -1154,11 +1170,12 @@
   return bubble_ui_info;
 }
 
-DownloadUIModel::BubbleUIInfo DownloadUIModel::GetBubbleUIInfo() const {
+DownloadUIModel::BubbleUIInfo DownloadUIModel::GetBubbleUIInfo(
+    bool is_download_bubble_v2) const {
   switch (GetState()) {
     case DownloadItem::IN_PROGRESS:
     case DownloadItem::COMPLETE:
-      return GetBubbleUIInfoForInProgressOrComplete();
+      return GetBubbleUIInfoForInProgressOrComplete(is_download_bubble_v2);
     case DownloadItem::INTERRUPTED: {
       const FailState fail_state = GetLastFailState();
       if (fail_state != FailState::USER_CANCELED) {
diff --git a/chrome/browser/download/download_ui_model.h b/chrome/browser/download/download_ui_model.h
index 1d34e96..2b3ebd23 100644
--- a/chrome/browser/download/download_ui_model.h
+++ b/chrome/browser/download/download_ui_model.h
@@ -161,6 +161,9 @@
                                   ui::ColorId color_id);
     BubbleUIInfo& AddPrimaryButton(DownloadCommands::Command command);
     BubbleUIInfo& AddCheckbox(const std::u16string& label);
+    // Add button to the subpage. Only two buttons are supported.
+    // The first one added is the primary, and the second one the secondary.
+    // The checkbox, if present, controls the secondary.
     BubbleUIInfo& AddSubpageButton(const std::u16string& label,
                                    DownloadCommands::Command command,
                                    bool is_prominent);
@@ -490,10 +493,11 @@
                               DownloadCommands::Command command);
 
   // Gets the information about the download bubbles subpage.
-  BubbleUIInfo GetBubbleUIInfo() const;
+  BubbleUIInfo GetBubbleUIInfo(bool is_download_bubble_v2) const;
   BubbleUIInfo GetBubbleUIInfoForInterrupted(
       offline_items_collection::FailState fail_state) const;
-  BubbleUIInfo GetBubbleUIInfoForInProgressOrComplete() const;
+  BubbleUIInfo GetBubbleUIInfoForInProgressOrComplete(
+      bool is_download_bubble_v2) const;
 
   // Returns |true| if this download should be displayed in the download bubble.
   virtual bool ShouldShowInBubble() const;
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn
index 03063f0..9af23fd 100644
--- a/chrome/browser/extensions/BUILD.gn
+++ b/chrome/browser/extensions/BUILD.gn
@@ -796,6 +796,7 @@
     "//chrome/browser/ui/tabs:tab_enums",
     "//chrome/browser/web_applications",
     "//components/cbor:cbor",
+    "//components/device_reauth",
     "//components/safe_browsing/content/browser",
     "//components/safe_browsing/core/browser:safe_browsing_metrics_collector",
     "//components/security_interstitials/content:security_interstitial_page",
diff --git a/chrome/browser/extensions/api/DEPS b/chrome/browser/extensions/api/DEPS
index c2f7fbe1..aa705a3 100644
--- a/chrome/browser/extensions/api/DEPS
+++ b/chrome/browser/extensions/api/DEPS
@@ -2,7 +2,7 @@
   "+apps",
   "+components/live_caption",
   "+services/device/public",
-
+  "+components/device_reauth",
    # Enable remote assistance on Chrome OS
   "+remoting/host",
 ]
diff --git a/chrome/browser/extensions/api/page_capture/page_capture_api.cc b/chrome/browser/extensions/api/page_capture/page_capture_api.cc
index 5f25da1f..ae20864 100644
--- a/chrome/browser/extensions/api/page_capture/page_capture_api.cc
+++ b/chrome/browser/extensions/api/page_capture/page_capture_api.cc
@@ -9,32 +9,20 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/callback_helpers.h"
 #include "base/files/file_util.h"
 #include "base/task/thread_pool.h"
 #include "build/chromeos_buildflags.h"
-#include "chrome/browser/browser_process.h"
 #include "chrome/browser/extensions/extension_tab_util.h"
 #include "chrome/browser/extensions/extension_util.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profiles_state.h"
 #include "components/sessions/content/session_tab_helper.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/child_process_security_policy.h"
-#include "content/public/browser/notification_details.h"
-#include "content/public/browser/notification_source.h"
-#include "content/public/browser/notification_types.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/mhtml_generation_params.h"
 #include "extensions/common/extension_messages.h"
 #include "extensions/common/permissions/permissions_data.h"
 
-#if BUILDFLAG(IS_CHROMEOS)
-#include "chrome/browser/chromeos/extensions/public_session_permission_helper.h"
-#include "extensions/common/permissions/api_permission_set.h"
-#endif
-
 using content::BrowserThread;
 using content::ChildProcessSecurityPolicy;
 using content::WebContents;
@@ -51,9 +39,6 @@
 const char kTabClosedError[] = "Cannot find the tab for this request.";
 const char kPageCaptureNotAllowed[] =
     "Don't have permissions required to capture this page.";
-#if BUILDFLAG(IS_CHROMEOS)
-const char kUserDenied[] = "User denied request.";
-#endif
 constexpr base::TaskTraits kCreateTemporaryFileTaskTraits = {
     // Requires IO.
     base::MayBlock(),
@@ -91,31 +76,6 @@
   params_ = SaveAsMHTML::Params::Create(args());
   EXTENSION_FUNCTION_VALIDATE(params_.get());
 
-#if BUILDFLAG(IS_CHROMEOS)
-  // In Public Sessions, extensions (and apps) are force-installed by admin
-  // policy so the user does not get a chance to review the permissions for
-  // these extensions. This is not acceptable from a security/privacy
-  // standpoint, so when an extension uses the PageCapture API for the first
-  // time, we show the user a dialog where they can choose whether to allow
-  // the extension access to the API.
-  // TODO(https://crbug.com/1269409): This bypasses the CanCaptureCurrentPage()
-  // check below, which means we don't check certain restrictions.
-  if (profiles::ArePublicSessionRestrictionsEnabled()) {
-    WebContents* web_contents = GetWebContents();
-    if (!web_contents) {
-      return RespondNow(Error(kTabClosedError));
-    }
-
-    permission_helper::HandlePermissionRequest(
-        *extension(), {mojom::APIPermissionID::kPageCapture}, web_contents,
-        base::BindOnce(
-            &PageCaptureSaveAsMHTMLFunction::ResolvePermissionRequest,
-            this),  // Callback increments refcount.
-        permission_helper::PromptFactory());
-    return RespondLater();
-  }
-#endif
-
   std::string error;
   if (!CanCaptureCurrentPage(&error)) {
     return RespondNow(Error(std::move(error)));
@@ -187,21 +147,6 @@
   Release();  // Balanced in Run()
 }
 
-#if BUILDFLAG(IS_CHROMEOS)
-void PageCaptureSaveAsMHTMLFunction::ResolvePermissionRequest(
-    const PermissionIDSet& allowed_permissions) {
-  if (allowed_permissions.ContainsID(
-          extensions::mojom::APIPermissionID::kPageCapture)) {
-    base::ThreadPool::PostTask(
-        FROM_HERE, kCreateTemporaryFileTaskTraits,
-        base::BindOnce(&PageCaptureSaveAsMHTMLFunction::CreateTemporaryFile,
-                       this));
-  } else {
-    ReturnFailure(kUserDenied);
-  }
-}
-#endif
-
 void PageCaptureSaveAsMHTMLFunction::CreateTemporaryFile() {
   bool success = base::CreateTemporaryFile(&mhtml_path_);
   content::GetIOThreadTaskRunner({})->PostTask(
diff --git a/chrome/browser/extensions/api/page_capture/page_capture_api.h b/chrome/browser/extensions/api/page_capture/page_capture_api.h
index 09aa6d5a..c31adf7 100644
--- a/chrome/browser/extensions/api/page_capture/page_capture_api.h
+++ b/chrome/browser/extensions/api/page_capture/page_capture_api.h
@@ -25,10 +25,6 @@
 
 namespace extensions {
 
-#if BUILDFLAG(IS_CHROMEOS)
-class PermissionIDSet;
-#endif
-
 class PageCaptureSaveAsMHTMLFunction : public ExtensionFunction {
  public:
   PageCaptureSaveAsMHTMLFunction();
@@ -51,11 +47,6 @@
   ResponseAction Run() override;
   bool OnMessageReceived(const IPC::Message& message) override;
 
-#if BUILDFLAG(IS_CHROMEOS)
-  // Resolves the API permission request in Public Sessions.
-  void ResolvePermissionRequest(const PermissionIDSet& allowed_permissions);
-#endif
-
   // Returns whether or not the extension has permission to capture the current
   // page. Sets |*error| to an error value on failure.
   bool CanCaptureCurrentPage(std::string* error);
diff --git a/chrome/browser/extensions/api/page_capture/page_capture_apitest.cc b/chrome/browser/extensions/api/page_capture/page_capture_apitest.cc
index 15672ba..0a39556 100644
--- a/chrome/browser/extensions/api/page_capture/page_capture_apitest.cc
+++ b/chrome/browser/extensions/api/page_capture/page_capture_apitest.cc
@@ -4,37 +4,15 @@
 
 #include <atomic>
 
-#include "base/base_switches.h"
 #include "base/command_line.h"
-#include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
-#include "chrome/browser/extensions/active_tab_permission_granter.h"
 #include "chrome/browser/extensions/api/page_capture/page_capture_api.h"
-#include "chrome/browser/extensions/extension_action_runner.h"
 #include "chrome/browser/extensions/extension_apitest.h"
-#include "chrome/browser/extensions/extension_util.h"
-#include "chrome/browser/extensions/tab_helper.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/test/base/ui_test_utils.h"
-#include "chromeos/login/login_state/scoped_test_public_session_login_state.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test.h"
-#include "content/public/test/test_utils.h"
-#include "extensions/browser/extension_dialog_auto_confirm.h"
-#include "extensions/common/permissions/permission_set.h"
-#include "extensions/common/permissions/permissions_data.h"
-#include "extensions/common/url_pattern_set.h"
-#include "extensions/test/extension_test_message_listener.h"
-#include "extensions/test/result_catcher.h"
 #include "net/dns/mock_host_resolver.h"
 #include "third_party/blink/public/common/switches.h"
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-#include "chromeos/login/login_state/login_state.h"
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
 namespace extensions {
 
 using ContextType = ExtensionApiTest::ContextType;
@@ -47,7 +25,7 @@
   }
 
   virtual ~PageCaptureSaveAsMHTMLDelegate() {
-    PageCaptureSaveAsMHTMLFunction::SetTestDelegate(NULL);
+    PageCaptureSaveAsMHTMLFunction::SetTestDelegate(nullptr);
   }
 
   void OnTemporaryFileCreated(
@@ -130,28 +108,4 @@
   WaitForFileCleanup(&delegate);
 }
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-IN_PROC_BROWSER_TEST_P(ExtensionPageCaptureApiTest,
-                       PublicSessionRequestAllowed) {
-  ASSERT_TRUE(StartEmbeddedTestServer());
-  PageCaptureSaveAsMHTMLDelegate delegate;
-  chromeos::ScopedTestPublicSessionLoginState login_state;
-  // Resolve Permission dialog with Allow.
-  ScopedTestDialogAutoConfirm auto_confirm(ScopedTestDialogAutoConfirm::ACCEPT);
-  ASSERT_TRUE(RunTest("page_capture")) << message_;
-  WaitForFileCleanup(&delegate);
-}
-
-IN_PROC_BROWSER_TEST_P(ExtensionPageCaptureApiTest,
-                       PublicSessionRequestDenied) {
-  ASSERT_TRUE(StartEmbeddedTestServer());
-  PageCaptureSaveAsMHTMLDelegate delegate;
-  chromeos::ScopedTestPublicSessionLoginState login_state;
-  // Resolve Permission dialog with Deny.
-  ScopedTestDialogAutoConfirm auto_confirm(ScopedTestDialogAutoConfirm::CANCEL);
-  ASSERT_TRUE(RunTest("page_capture", "REQUEST_DENIED")) << message_;
-  EXPECT_EQ(0, delegate.temp_file_count());
-}
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
 }  // namespace extensions
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc
index cce390f..9dcd322 100644
--- a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc
+++ b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc
@@ -36,6 +36,7 @@
 #include "components/password_manager/core/browser/password_manager_features_util.h"
 #include "components/password_manager/core/browser/password_manager_util.h"
 #include "components/password_manager/core/browser/password_sync_util.h"
+#include "components/password_manager/core/common/password_manager_features.h"
 #include "components/prefs/pref_service.h"
 #include "components/signin/public/base/signin_metrics.h"
 #include "components/sync/driver/sync_service.h"
@@ -53,6 +54,7 @@
 #endif
 
 #if BUILDFLAG(IS_MAC)
+#include "chrome/browser/device_reauth/chrome_biometric_authenticator_factory.h"
 #include "chrome/browser/password_manager/password_manager_util_mac.h"
 #endif
 
@@ -409,8 +411,31 @@
       web_contents_->GetTopLevelNativeWindow(), purpose);
   std::move(callback).Run(result);
 #elif BUILDFLAG(IS_MAC)
-  bool result = password_manager_util_mac::AuthenticateUser(purpose);
-  std::move(callback).Run(result);
+  if (base::FeatureList::IsEnabled(
+          password_manager::features::kBiometricAuthenticationInSettings)) {
+    scoped_refptr<device_reauth::BiometricAuthenticator>
+        biometric_authenticator =
+            ChromeBiometricAuthenticatorFactory::GetInstance()
+                ->GetOrCreateBiometricAuthenticator();
+    base::OnceCallback<void()> on_reauth_completed =
+        base::BindOnce(&PasswordsPrivateDelegateImpl::OnReauthCompleted,
+                       weak_ptr_factory_.GetWeakPtr());
+
+    biometric_authenticator->AuthenticateWithMessage(
+        device_reauth::BiometricAuthRequester::kPasswordsInSettings,
+        password_manager_util_mac::GetMessageForBiometricLoginPrompt(purpose),
+        std::move(callback).Then(std::move(on_reauth_completed)));
+
+    // If AuthenticateWithMessage is called again(UI isn't blocked so user might
+    // click multiple times on the button), it invalidates the old request which
+    // triggers PasswordsPrivateDelegateImpl::OnReauthCompleted which resets
+    // biometric_authenticator_. Having a local variable solves that problem as
+    // there's a second scoped_refptr for the authenticator object.
+    biometric_authenticator_ = std::move(biometric_authenticator);
+  } else {
+    bool result = password_manager_util_mac::AuthenticateUser(purpose);
+    std::move(callback).Run(result);
+  }
 #elif BUILDFLAG(IS_CHROMEOS_ASH)
   bool result =
       IsOsReauthAllowedAsh(profile_, GetAuthTokenLifetimeForPurpose(purpose));
@@ -728,6 +753,11 @@
 void PasswordsPrivateDelegateImpl::Shutdown() {
   password_account_storage_settings_watcher_.reset();
   password_manager_porter_.reset();
+  biometric_authenticator_.reset();
+}
+
+void PasswordsPrivateDelegateImpl::OnReauthCompleted() {
+  biometric_authenticator_.reset();
 }
 
 void PasswordsPrivateDelegateImpl::ExecuteFunction(base::OnceClosure callback) {
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.h b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.h
index 37c48e7d..a826b77 100644
--- a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.h
+++ b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.h
@@ -21,6 +21,7 @@
 #include "chrome/browser/extensions/api/passwords_private/passwords_private_utils.h"
 #include "chrome/browser/ui/passwords/settings/password_manager_porter.h"
 #include "chrome/common/extensions/api/passwords_private.h"
+#include "components/device_reauth/biometric_authenticator.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/password_manager/core/browser/password_access_authenticator.h"
 #include "components/password_manager/core/browser/password_account_storage_settings_watcher.h"
@@ -194,6 +195,9 @@
       const password_manager::CredentialUIEntry& entry,
       api::passwords_private::PlaintextReason reason);
 
+  // Callback for biometric authentication after authentication check.
+  void OnReauthCompleted();
+
   // Not owned by this class.
   raw_ptr<Profile> profile_;
 
@@ -238,6 +242,9 @@
   // NativeWindow for the window where the API was called.
   raw_ptr<content::WebContents> web_contents_;
 
+  // Biometric authenticator used to authenticate user on Mac in settings.
+  scoped_refptr<device_reauth::BiometricAuthenticator> biometric_authenticator_;
+
   base::WeakPtrFactory<PasswordsPrivateDelegateImpl> weak_ptr_factory_{this};
 };
 
diff --git a/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher.h b/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher.h
new file mode 100644
index 0000000..c6e1b75
--- /dev/null
+++ b/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher.h
@@ -0,0 +1,44 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_FAST_CHECKOUT_FAST_CHECKOUT_CAPABILITIES_FETCHER_H_
+#define CHROME_BROWSER_FAST_CHECKOUT_FAST_CHECKOUT_CAPABILITIES_FETCHER_H_
+
+#include "base/callback_forward.h"
+#include "components/keyed_service/core/keyed_service.h"
+
+namespace autofill {
+class FormSignature;
+}  // namespace autofill
+
+namespace url {
+class Origin;
+}  // namespace url
+
+// A service that provides information about whether a form on a given origin
+// is supported for FastCheckout flows. The service is used as one of several
+// inputs that determine whether to offer a FastCheckout flow to a user
+// interacting with an input form field.
+// Availability is queried in a privacy-preserving manner by utilizing
+// `AutofillAssistant::GetCapabilitiesByHashPrefix()`.
+class FastCheckoutCapabilitiesFetcher : public KeyedService {
+ public:
+  // Callback with a `bool` parameter that indicates whether the availability
+  // request was successful. `false` indicates an RPC error.
+  using Callback = base::OnceCallback<void(bool)>;
+
+  // Sends a request to determine which (if any) forms are supported for
+  // FastCheckout on `origin`. Calls `callback` to indicate the success of
+  // the request (and not whether origin is supported).
+  virtual void FetchAvailability(const url::Origin& origin,
+                                 Callback callback) = 0;
+  // Checks whether a form with `form_signature` on `origin` is supported
+  // for FastCheckout. Requires `FetchAvailability` to have been completed
+  // for this origin or will return `false` otherwise.
+  virtual bool IsTriggerFormSupported(
+      const url::Origin& origin,
+      autofill::FormSignature form_signature) = 0;
+};
+
+#endif  // CHROME_BROWSER_FAST_CHECKOUT_FAST_CHECKOUT_CAPABILITIES_FETCHER_H_
diff --git a/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_impl.cc b/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_impl.cc
new file mode 100644
index 0000000..0cb8836
--- /dev/null
+++ b/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_impl.cc
@@ -0,0 +1,36 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_impl.h"
+
+#include <memory>
+
+#include "base/callback.h"
+#include "base/notreached.h"
+#include "components/autofill/core/common/signatures.h"
+#include "components/autofill_assistant/browser/public/autofill_assistant.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "url/origin.h"
+
+FastCheckoutCapabilitiesFetcherImpl::FastCheckoutCapabilitiesFetcherImpl(
+    std::unique_ptr<autofill_assistant::AutofillAssistant> autofill_assistant)
+    : autofill_assistant_(std::move(autofill_assistant)) {}
+
+FastCheckoutCapabilitiesFetcherImpl::~FastCheckoutCapabilitiesFetcherImpl() =
+    default;
+
+void FastCheckoutCapabilitiesFetcherImpl::FetchAvailability(
+    const url::Origin& origin,
+    Callback callback) {
+  // TODO(crbug.com/1350456): Implement.
+  NOTIMPLEMENTED();
+}
+
+bool FastCheckoutCapabilitiesFetcherImpl::IsTriggerFormSupported(
+    const url::Origin& origin,
+    autofill::FormSignature form_signature) {
+  // TODO(crbug.com/1350456): Implement.
+  NOTIMPLEMENTED();
+  return false;
+}
diff --git a/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_impl.h b/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_impl.h
new file mode 100644
index 0000000..032a612
--- /dev/null
+++ b/chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher_impl.h
@@ -0,0 +1,51 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_FAST_CHECKOUT_FAST_CHECKOUT_CAPABILITIES_FETCHER_IMPL_H_
+#define CHROME_BROWSER_FAST_CHECKOUT_FAST_CHECKOUT_CAPABILITIES_FETCHER_IMPL_H_
+
+#include <memory>
+
+#include "base/callback_forward.h"
+#include "chrome/browser/fast_checkout/fast_checkout_capabilities_fetcher.h"
+#include "components/keyed_service/core/keyed_service.h"
+
+namespace autofill {
+class FormSignature;
+}  // namespace autofill
+
+namespace autofill_assistant {
+class AutofillAssistant;
+}  // namespace autofill_assistant
+
+namespace url {
+class Origin;
+}  // namespace url
+
+class FastCheckoutCapabilitiesFetcherImpl
+    : public FastCheckoutCapabilitiesFetcher {
+ public:
+  explicit FastCheckoutCapabilitiesFetcherImpl(
+      std::unique_ptr<autofill_assistant::AutofillAssistant>
+          autofill_assistant);
+  ~FastCheckoutCapabilitiesFetcherImpl() override;
+
+  FastCheckoutCapabilitiesFetcherImpl(
+      const FastCheckoutCapabilitiesFetcherImpl&) = delete;
+  FastCheckoutCapabilitiesFetcherImpl& operator=(
+      const FastCheckoutCapabilitiesFetcherImpl&) = delete;
+
+  // CapabilitiesFetcher:
+  void FetchAvailability(const url::Origin& origin, Callback callback) override;
+  bool IsTriggerFormSupported(const url::Origin& origin,
+                              autofill::FormSignature form_signature) override;
+
+ private:
+  // An `AutofillAssistant` instance to gain access to
+  // `GetCapabilitiesByHashPrefix` RPC calls.
+  const std::unique_ptr<autofill_assistant::AutofillAssistant>
+      autofill_assistant_;
+};
+
+#endif  // CHROME_BROWSER_FAST_CHECKOUT_FAST_CHECKOUT_CAPABILITIES_FETCHER_IMPL_H_
diff --git a/chrome/browser/media/webrtc/webrtc_desktop_capture_browsertest.cc b/chrome/browser/media/webrtc/webrtc_desktop_capture_browsertest.cc
index 86a0ff66..cbd20511 100644
--- a/chrome/browser/media/webrtc/webrtc_desktop_capture_browsertest.cc
+++ b/chrome/browser/media/webrtc/webrtc_desktop_capture_browsertest.cc
@@ -304,13 +304,13 @@
 
 IN_PROC_BROWSER_TEST_F(WebRtcDesktopCaptureBrowserTest,
                        TabCaptureProvidesMinFps) {
-  constexpr int kFps = 25;
-  constexpr const char* const kFpsString = "25";
+  constexpr int kFps = 30;
+  constexpr const char* const kFpsString = "30";
   constexpr int kTestTimeSeconds = 2;
   // We wait with measuring frame rate until a few frames has passed. This is
   // because the frame rate frame dropper in VideoTrackAdapter is pretty
   // aggressive dropping frames when the stream starts.
-  constexpr int kNumFramesBeforeStabilization = 10;
+  constexpr int kNumFramesBeforeStabilization = kFps;
 
   InitializeTabSharingForFirstTab(
       base::BindOnce(GetDesktopMediaIDForTab, base::Unretained(browser()), 1),
@@ -342,8 +342,13 @@
       first_tab, base::Milliseconds(50)));
   int average_fps = (final_frame_counter - initial_frame_counter) * 1000 /
                     (final_timestamp - initial_timestamp).InMilliseconds();
-  // Expect at least 50% of the expected frames to aggressively combat flakes.
-  ASSERT_GE(average_fps, kFps / 2);
+  // MediaStreamVideoTrack upholds the min fps by way of an idle timer getting
+  // reset for every received frame from the source. Sources being slow to
+  // provide frames or plumbed main thread will ensure that the FPS provided is
+  // actually always strictly lower than the requested minimum.
+  // Expect at least 1/3 of the expected frames have appeared to aggressively
+  // combat flakes.
+  ASSERT_GE(average_fps, kFps / 3);
 }
 
 // TODO(crbug.com/796889): Enable on Mac when thread check crash is fixed.
diff --git a/chrome/browser/page_info/about_this_site_controller_android.cc b/chrome/browser/page_info/about_this_site_controller_android.cc
index a45abc51c..fb74eb15 100644
--- a/chrome/browser/page_info/about_this_site_controller_android.cc
+++ b/chrome/browser/page_info/about_this_site_controller_android.cc
@@ -6,7 +6,6 @@
 
 #include <jni.h>
 #include "base/android/jni_array.h"
-#include "base/android/jni_string.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/page_info/about_this_site_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
@@ -51,3 +50,9 @@
   info->SerializeToArray(data.data(), size);
   return base::android::ToJavaByteArray(env, data.data(), size);
 }
+
+static void JNI_PageInfoAboutThisSiteController_OnAboutThisSiteRowClicked(
+    JNIEnv* env,
+    jboolean j_withDescription) {
+  page_info::AboutThisSiteService::OnAboutThisSiteRowClicked(j_withDescription);
+}
diff --git a/chrome/browser/page_load_metrics/integration_tests/total_input_delay_browsertest.cc b/chrome/browser/page_load_metrics/integration_tests/total_input_delay_browsertest.cc
index 01f6ef60..2122a9f 100644
--- a/chrome/browser/page_load_metrics/integration_tests/total_input_delay_browsertest.cc
+++ b/chrome/browser/page_load_metrics/integration_tests/total_input_delay_browsertest.cc
@@ -63,7 +63,14 @@
       PageLoad::kInteractiveTiming_TotalAdjustedInputDelayName, int64_t(0), 0);
 }
 
-IN_PROC_BROWSER_TEST_F(TotalInputDelayIntegrationTest, MultipleInputEvents) {
+// TODO(crbug.com/1352082): Fix flakiness.
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
+#define MAYBE_MultipleInputEvents DISABLED_MultipleInputEvents
+#else
+#define MAYBE_MultipleInputEvents MultipleInputEvents
+#endif
+IN_PROC_BROWSER_TEST_F(TotalInputDelayIntegrationTest,
+                       MAYBE_MultipleInputEvents) {
   auto waiter = std::make_unique<page_load_metrics::PageLoadMetricsTestWaiter>(
       web_contents());
   waiter->AddPageExpectation(page_load_metrics::PageLoadMetricsTestWaiter::
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
index 76d99a7..aee80dd 100644
--- a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
+++ b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
@@ -713,9 +713,17 @@
   main_frame_intersection_expectation_waiter->Wait();
 }
 
+// TODO(crbug.com/1352092): Fix flakiness.
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
+#define MAYBE_NonZeroMainFrameScrollOffset_NestedCrossOriginFrame_MainFrameIntersection \
+  DISABLED_NonZeroMainFrameScrollOffset_NestedCrossOriginFrame_MainFrameIntersection
+#else
+#define MAYBE_NonZeroMainFrameScrollOffset_NestedCrossOriginFrame_MainFrameIntersection \
+  NonZeroMainFrameScrollOffset_NestedCrossOriginFrame_MainFrameIntersection
+#endif
 IN_PROC_BROWSER_TEST_F(
     PageLoadMetricsBrowserTest,
-    NonZeroMainFrameScrollOffset_NestedCrossOriginFrame_MainFrameIntersection) {
+    MAYBE_NonZeroMainFrameScrollOffset_NestedCrossOriginFrame_MainFrameIntersection) {
   ASSERT_TRUE(embedded_test_server()->Start());
   GURL url = embedded_test_server()->GetURL(
       "a.com", "/scroll/scrollable_page_with_content.html");
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 528159f..9005cfd 100644
--- a/chrome/browser/password_manager/android/password_store_android_backend.cc
+++ b/chrome/browser/password_manager/android/password_store_android_backend.cc
@@ -52,6 +52,10 @@
 constexpr base::TimeDelta kAsyncTaskTimeout = base::Seconds(30);
 constexpr char kUPMActiveHistogram[] =
     "PasswordManager.UnifiedPasswordManager.ActiveStatus";
+constexpr char kAliveAfterApiNotConnectedHistogram[] =
+    "PasswordManager.AliveAfterApiNotConnectedError";
+constexpr base::TimeDelta kReportAliveAfterApiNotConnectedDelay =
+    base::Seconds(10);
 
 using base::UTF8ToUTF16;
 using password_manager::GetExpressionForFederatedMatching;
@@ -62,6 +66,18 @@
 using JobId = PasswordStoreAndroidBackendBridge::JobId;
 using SuccessStatus = PasswordStoreBackendMetricsRecorder::SuccessStatus;
 
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+enum class AliveAfterApiNotConnectedStatus {
+  // Alive on receiving the error, this code is the basis for the analysis.
+  kAliveOnError = 0,
+  // Alive after a delay, Chrome didn't shutdown/restart since receiving the
+  // error.
+  kAliveAfterDelay = 1,
+
+  kMaxValue = kAliveAfterDelay
+};
+
 std::vector<std::unique_ptr<PasswordForm>> WrapPasswordsIntoPointers(
     std::vector<PasswordForm> passwords) {
   std::vector<std::unique_ptr<PasswordForm>> password_ptrs;
@@ -721,6 +737,21 @@
       prefs_->SetDouble(prefs::kTimeOfLastMigrationAttempt, 0.0);
       prefs_->SetBoolean(prefs::kSettingsMigratedToUPM, false);
     }
+
+    if (static_cast<AndroidBackendAPIErrorCode>(api_error) ==
+        AndroidBackendAPIErrorCode::kApiNotConnected) {
+      base::UmaHistogramEnumeration(
+          kAliveAfterApiNotConnectedHistogram,
+          AliveAfterApiNotConnectedStatus::kAliveOnError);
+      main_task_runner_->PostDelayedTask(
+          FROM_HERE,
+          base::BindOnce(static_cast<void (*)(const char*,
+                                              AliveAfterApiNotConnectedStatus)>(
+                             &base::UmaHistogramEnumeration),
+                         kAliveAfterApiNotConnectedHistogram,
+                         AliveAfterApiNotConnectedStatus::kAliveAfterDelay),
+          kReportAliveAfterApiNotConnectedDelay);
+    }
   }
   PasswordStoreBackendError reported_error =
       BackendErrorFromAndroidBackendError(error);
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 11b2ffc..cbdbfead 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
@@ -853,6 +853,50 @@
   histogram_tester.ExpectBucketCount(kAPIErrorMetric, kInternalErrorCode, 1);
 }
 
+TEST_F(PasswordStoreAndroidBackendTest, RecordsAliveStatusOnApiNotConnected) {
+  constexpr char kAliveAfterErrorMetric[] =
+      "PasswordManager.AliveAfterApiNotConnectedError";
+
+  base::HistogramTester histogram_tester;
+
+  backend().InitBackend(PasswordStoreAndroidBackend::RemoteChangesReceived(),
+                        base::RepeatingClosure(), base::DoNothing());
+  backend().OnSyncServiceInitialized(sync_service());
+
+  ASSERT_FALSE(sync_service()->GetAuthError().IsTransientError());
+  ASSERT_FALSE(sync_service()->GetAuthError().IsPersistentError());
+
+  const JobId kJobId{1337};
+  base::MockCallback<LoginsOrErrorReply> mock_reply;
+  EXPECT_CALL(*bridge(), GetAllLogins).WillOnce(Return(kJobId));
+  backend().GetAllLoginsAsync(mock_reply.Get());
+  EXPECT_CALL(mock_reply,
+              Run(ExpectError(PasswordStoreBackendError::kUnrecoverable)));
+  AndroidBackendError error{AndroidBackendErrorType::kExternalError};
+  // Simulate receiving API_NOT_CONNECTED code.
+  const int kApiNotConnectedErrorCode =
+      static_cast<int>(AndroidBackendAPIErrorCode::kApiNotConnected);
+  error.api_error_code = absl::optional<int>(kApiNotConnectedErrorCode);
+  consumer().OnError(kJobId, std::move(error));
+
+  const int kAliveAfterApiNotConnectedOnErrorStatus = 0;
+  const int kAliveAfterApiNotConnectedAfterDelayStatus = 1;
+
+  // Fast forward to right before expected metric reporting.
+  task_environment_.FastForwardBy(base::Seconds(9));
+  histogram_tester.ExpectBucketCount(
+      kAliveAfterErrorMetric, kAliveAfterApiNotConnectedOnErrorStatus, 1);
+  histogram_tester.ExpectBucketCount(
+      kAliveAfterErrorMetric, kAliveAfterApiNotConnectedAfterDelayStatus, 0);
+
+  // Metric should be eventually reported after a 10 seconds delay.
+  task_environment_.FastForwardBy(base::Seconds(1));
+  histogram_tester.ExpectBucketCount(
+      kAliveAfterErrorMetric, kAliveAfterApiNotConnectedOnErrorStatus, 1);
+  histogram_tester.ExpectBucketCount(
+      kAliveAfterErrorMetric, kAliveAfterApiNotConnectedAfterDelayStatus, 1);
+}
+
 TEST_F(PasswordStoreAndroidBackendTest,
        OnUnrecoverablApiErrorShowsUIFlagEnabled) {
   base::test::ScopedFeatureList scoped_feature_list{
diff --git a/chrome/browser/password_manager/password_manager_util_mac.h b/chrome/browser/password_manager/password_manager_util_mac.h
index 1a4d76c..c3f9486 100644
--- a/chrome/browser/password_manager/password_manager_util_mac.h
+++ b/chrome/browser/password_manager/password_manager_util_mac.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_MANAGER_UTIL_MAC_H_
 #define CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_MANAGER_UTIL_MAC_H_
 
+#include <string>
+
 #include "components/password_manager/core/browser/reauth_purpose.h"
 
 namespace password_manager_util_mac {
@@ -13,6 +15,10 @@
 // the user was successfully authenticated.
 bool AuthenticateUser(password_manager::ReauthPurpose purpose);
 
+// Returns message that will appear in the login prompt
+std::u16string GetMessageForBiometricLoginPrompt(
+    password_manager::ReauthPurpose purpose);
+
 }  // namespace password_manager_util_mac
 
 #endif  // CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_MANAGER_UTIL_MAC_H_
diff --git a/chrome/browser/password_manager/password_manager_util_mac.mm b/chrome/browser/password_manager/password_manager_util_mac.mm
index 55e41d5..a8af12f 100644
--- a/chrome/browser/password_manager/password_manager_util_mac.mm
+++ b/chrome/browser/password_manager/password_manager_util_mac.mm
@@ -12,6 +12,7 @@
 #include "base/mac/foundation_util.h"
 #include "base/mac/scoped_authorizationref.h"
 #include "chrome/grit/chromium_strings.h"
+#include "chrome/grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
 
 namespace password_manager_util_mac {
@@ -55,4 +56,23 @@
   return authorization.get() != NULL;
 }
 
+std::u16string GetMessageForBiometricLoginPrompt(
+    password_manager::ReauthPurpose purpose) {
+  // Depending on the `purpose` different message will be returned.
+  switch (purpose) {
+    case password_manager::ReauthPurpose::VIEW_PASSWORD:
+      return l10n_util::GetStringUTF16(
+          IDS_PASSWORDS_PAGE_AUTHENTICATION_PROMPT_BIOMETRIC_SUFFIX);
+    case password_manager::ReauthPurpose::COPY_PASSWORD:
+      return l10n_util::GetStringUTF16(
+          IDS_PASSWORDS_PAGE_COPY_AUTHENTICATION_PROMPT_BIOMETRIC_SUFFIX);
+    case password_manager::ReauthPurpose::EDIT_PASSWORD:
+      return l10n_util::GetStringUTF16(
+          IDS_PASSWORDS_PAGE_EDIT_AUTHENTICATION_PROMPT_BIOMETRIC_SUFFIX);
+    case password_manager::ReauthPurpose::EXPORT:
+      return l10n_util::GetStringUTF16(
+          IDS_PASSWORDS_PAGE_EXPORT_AUTHENTICATION_PROMPT_BIOMETRIC_SUFFIX);
+  }
+}
+
 }  // namespace password_manager_util_mac
diff --git a/chrome/browser/privacy_guide/android/BUILD.gn b/chrome/browser/privacy_guide/android/BUILD.gn
index 66810a21..0160ece 100644
--- a/chrome/browser/privacy_guide/android/BUILD.gn
+++ b/chrome/browser/privacy_guide/android/BUILD.gn
@@ -7,9 +7,9 @@
 android_library("java") {
   sources = [
     "java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideBottomSheetView.java",
-    "java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideDialog.java",
     "java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideExplanationHeading.java",
     "java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideExplanationItem.java",
+    "java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideFragment.java",
     "java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuidePagerAdapter.java",
   ]
   deps = [
@@ -18,6 +18,7 @@
     "//components/browser_ui/widget/android:java",
     "//third_party/androidx:androidx_annotation_annotation_java",
     "//third_party/androidx:androidx_appcompat_appcompat_java",
+    "//third_party/androidx:androidx_fragment_fragment_java",
     "//third_party/androidx:androidx_recyclerview_recyclerview_java",
     "//third_party/androidx:androidx_viewpager2_viewpager2_java",
     "//ui/android:ui_full_java",
@@ -25,6 +26,23 @@
   resources_package = "org.chromium.chrome.browser.privacy_guide"
 }
 
+android_library("javatests") {
+  testonly = true
+  sources = [ "javatests/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideFragmentTest.java" ]
+  deps = [
+    ":java",
+    "//base:base_java_test_support",
+    "//chrome/browser/flags:java",
+    "//chrome/browser/settings:test_support_java",
+    "//chrome/test/android:chrome_java_test_support_common",
+    "//third_party/android_deps:espresso_java",
+    "//third_party/androidx:androidx_test_runner_java",
+    "//third_party/hamcrest:hamcrest_core_java",
+    "//third_party/junit:junit",
+    "//ui/android:ui_java_test_support",
+  ]
+}
+
 android_resources("java_resources") {
   sources = [
     "java/res/drawable/privacy_guide_cookies_image.xml",
@@ -34,10 +52,10 @@
     "java/res/drawable/privacy_guide_sb_image.xml",
     "java/res/drawable/privacy_guide_sync_image.xml",
     "java/res/layout/privacy_guide_cookies_step.xml",
-    "java/res/layout/privacy_guide_dialog.xml",
     "java/res/layout/privacy_guide_done.xml",
     "java/res/layout/privacy_guide_explanation_heading.xml",
     "java/res/layout/privacy_guide_explanation_item.xml",
+    "java/res/layout/privacy_guide_fragment.xml",
     "java/res/layout/privacy_guide_msbb_step.xml",
     "java/res/layout/privacy_guide_sb_enhanced_explanation.xml",
     "java/res/layout/privacy_guide_sb_standard_explanation.xml",
diff --git a/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_cookies_step.xml b/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_cookies_step.xml
index 411452d..71d93d2 100644
--- a/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_cookies_step.xml
+++ b/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_cookies_step.xml
@@ -6,7 +6,7 @@
 <ScrollView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/scroll_view"
+    android:id="@+id/cookies_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
diff --git a/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_dialog.xml b/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_dialog.xml
deleted file mode 100644
index d92b87b..0000000
--- a/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_dialog.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2021 The Chromium Authors. All rights reserved.
-     Use of this source code is governed by a BSD-style license that can be
-     found in the LICENSE file. -->
-<androidx.coordinatorlayout.widget.CoordinatorLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="@macro/default_bg_color">
-
-    <com.google.android.material.appbar.AppBarLayout
-        android:id="@+id/app_bar_layout"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content">
-
-        <com.google.android.material.appbar.MaterialToolbar
-            android:id="@+id/toolbar"
-            android:layout_width="match_parent"
-            android:layout_height="@dimen/toolbar_height_no_shadow"/>
-    </com.google.android.material.appbar.AppBarLayout>
-
-    <FrameLayout
-        android:id="@+id/dialog_content"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        app:layout_behavior="@string/appbar_scrolling_view_behavior">
-    </FrameLayout>
-</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_done.xml b/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_done.xml
index c4f0bcc..68a5194 100644
--- a/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_done.xml
+++ b/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_done.xml
@@ -29,8 +29,8 @@
                 android:layout_marginVertical="32dp"
                 android:layout_height="@dimen/privacy_guide_illustration_height"
                 android:layout_width="@dimen/privacy_guide_illustration_width"
-                android:src="@drawable/privacy_guide_done_image"
-                android:importantForAccessibility="no" />
+                android:importantForAccessibility="no"
+                app:srcCompat="@drawable/privacy_guide_done_image" />
 
             <TextView
                 android:id="@+id/done_title"
diff --git a/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_fragment.xml b/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_fragment.xml
new file mode 100644
index 0000000..8efa6ba
--- /dev/null
+++ b/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_fragment.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/fragment_content"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    app:layout_behavior="@string/appbar_scrolling_view_behavior">
+</FrameLayout>
\ No newline at end of file
diff --git a/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_msbb_step.xml b/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_msbb_step.xml
index f0067ea..fad5771 100644
--- a/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_msbb_step.xml
+++ b/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_msbb_step.xml
@@ -6,12 +6,12 @@
 <ScrollView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/scroll_view"
+    android:id="@+id/msbb_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
     <LinearLayout
-        android:id="@+id/welcome_main_layout"
+        android:id="@+id/msbb_main_layout"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:animateLayoutChanges="true"
diff --git a/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_sb_step.xml b/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_sb_step.xml
index 98864e1..a76e367 100644
--- a/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_sb_step.xml
+++ b/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_sb_step.xml
@@ -6,7 +6,7 @@
 <ScrollView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/scroll_view"
+    android:id="@+id/sb_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
diff --git a/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_steps.xml b/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_steps.xml
index 65be487..c8a9d7ac 100644
--- a/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_steps.xml
+++ b/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_steps.xml
@@ -21,7 +21,7 @@
             android:id="@+id/review_viewpager"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
-            app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
+            app:layout_behavior="@string/appbar_scrolling_view_behavior" />
 
     </FrameLayout>
 
diff --git a/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_sync_step.xml b/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_sync_step.xml
index ef93bae..6b193e0 100644
--- a/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_sync_step.xml
+++ b/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_sync_step.xml
@@ -6,7 +6,7 @@
 <ScrollView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/scroll_view"
+    android:id="@+id/sync_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
diff --git a/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_welcome.xml b/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_welcome.xml
index 23ff40c..4fc3a62 100644
--- a/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_welcome.xml
+++ b/chrome/browser/privacy_guide/android/java/res/layout/privacy_guide_welcome.xml
@@ -5,6 +5,8 @@
 
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/welcome_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical">
@@ -28,8 +30,8 @@
                 android:layout_marginVertical="32dp"
                 android:layout_height="@dimen/privacy_guide_illustration_height"
                 android:layout_width="@dimen/privacy_guide_illustration_width"
-                android:src="@drawable/privacy_guide_illustration"
-                android:importantForAccessibility="no" />
+                android:importantForAccessibility="no"
+                app:srcCompat="@drawable/privacy_guide_illustration" />
 
             <TextView
                 android:id="@+id/welcome_title"
diff --git a/chrome/browser/privacy_guide/android/java/res/menu/privacy_guide_toolbar_menu.xml b/chrome/browser/privacy_guide/android/java/res/menu/privacy_guide_toolbar_menu.xml
index fbec6e9..bc180fd4 100644
--- a/chrome/browser/privacy_guide/android/java/res/menu/privacy_guide_toolbar_menu.xml
+++ b/chrome/browser/privacy_guide/android/java/res/menu/privacy_guide_toolbar_menu.xml
@@ -9,7 +9,7 @@
       android:id="@+id/close_menu_id"
       android:icon="@drawable/btn_close"
       android:title="@string/close"
-      app:showAsAction="ifRoom"
+      android:showAsAction="ifRoom"
       app:iconTint="@color/default_icon_color_tint_list" />
 
 </menu>
diff --git a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideDialog.java b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideDialog.java
deleted file mode 100644
index 97b6dc73..0000000
--- a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideDialog.java
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.privacy_guide;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-
-import androidx.appcompat.widget.Toolbar;
-import androidx.viewpager2.widget.ViewPager2;
-
-import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
-import org.chromium.ui.widget.ButtonCompat;
-
-/**
- * UI for the Privacy Guide dialog in Privacy and security settings.
- */
-public class PrivacyGuideDialog {
-    private LayoutInflater mLayoutInflater;
-    private ViewGroup mContainer;
-    private View mDialogView;
-    private ViewPager2 mViewPager;
-    private PrivacyGuidePagerAdapter mPagerAdapter;
-    private ButtonCompat mNextButton;
-    private ButtonCompat mBackButton;
-    private ButtonCompat mFinishButton;
-    private BottomSheetController mBottomSheetController;
-
-    public PrivacyGuideDialog(
-            Context context, ViewGroup container, BottomSheetController controller) {
-        mContainer = container;
-        mBottomSheetController = controller;
-        mLayoutInflater = LayoutInflater.from(context);
-        mDialogView = mLayoutInflater.inflate(R.layout.privacy_guide_dialog, null);
-
-        Toolbar toolbar = (Toolbar) mDialogView.findViewById(R.id.toolbar);
-        toolbar.setTitle(R.string.prefs_privacy_guide_title);
-        toolbar.inflateMenu(R.menu.privacy_guide_toolbar_menu);
-        toolbar.setOnMenuItemClickListener(this::onMenuItemClick);
-
-        displayWelcomePage();
-    }
-
-    /** Displays the dialog in a container given at construction time. */
-    public void show() {
-        mContainer.addView(mDialogView);
-        mContainer.setVisibility(View.VISIBLE);
-    }
-
-    /** Hides the dialog. */
-    public void dismiss() {
-        mContainer.removeView(mDialogView);
-        mContainer.setVisibility(View.GONE);
-    }
-
-    private boolean onMenuItemClick(MenuItem menuItem) {
-        if (menuItem.getItemId() == R.id.close_menu_id) {
-            dismiss();
-            return true;
-        }
-        return false;
-    }
-
-    private void displayWelcomePage() {
-        FrameLayout content = mDialogView.findViewById(R.id.dialog_content);
-        content.removeAllViews();
-        mLayoutInflater.inflate(R.layout.privacy_guide_welcome, content);
-
-        ButtonCompat welcomeButton = (ButtonCompat) mDialogView.findViewById(R.id.start_button);
-        welcomeButton.setOnClickListener((View v) -> displayMainFlow());
-    }
-
-    private void displayMainFlow() {
-        FrameLayout content = mDialogView.findViewById(R.id.dialog_content);
-        content.removeAllViews();
-        mLayoutInflater.inflate(R.layout.privacy_guide_steps, content);
-
-        mViewPager = (ViewPager2) mDialogView.findViewById(R.id.review_viewpager);
-        mPagerAdapter = new PrivacyGuidePagerAdapter(mBottomSheetController);
-        mViewPager.setAdapter(mPagerAdapter);
-
-        mNextButton = (ButtonCompat) mDialogView.findViewById(R.id.next_button);
-        mNextButton.setOnClickListener((View v) -> nextStep());
-
-        mBackButton = (ButtonCompat) mDialogView.findViewById(R.id.back_button);
-        mBackButton.setOnClickListener((View v) -> previousStep());
-
-        mFinishButton = (ButtonCompat) mDialogView.findViewById(R.id.finish_button);
-        mFinishButton.setOnClickListener((View v) -> displayDonePage());
-    }
-
-    private void displayDonePage() {
-        FrameLayout content = mDialogView.findViewById(R.id.dialog_content);
-        content.removeAllViews();
-        mLayoutInflater.inflate(R.layout.privacy_guide_done, content);
-
-        ButtonCompat doneButton = (ButtonCompat) mDialogView.findViewById(R.id.done_button);
-        doneButton.setOnClickListener((View v) -> dismiss());
-    }
-
-    private void nextStep() {
-        int nextIdx = mViewPager.getCurrentItem() + 1;
-        if (nextIdx < mPagerAdapter.getItemCount()) {
-            mViewPager.setCurrentItem(nextIdx);
-        }
-        mBackButton.setVisibility(View.VISIBLE);
-        if (nextIdx + 1 == mPagerAdapter.getItemCount()) {
-            mNextButton.setVisibility(View.GONE);
-            mFinishButton.setVisibility(View.VISIBLE);
-        }
-    }
-
-    private void previousStep() {
-        mFinishButton.setVisibility(View.GONE);
-        int prevIdx = mViewPager.getCurrentItem() - 1;
-        if (prevIdx >= 0) {
-            mViewPager.setCurrentItem(prevIdx);
-        }
-        mNextButton.setVisibility(View.VISIBLE);
-        if (prevIdx == 0) {
-            mBackButton.setVisibility(View.INVISIBLE);
-        }
-    }
-}
diff --git a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideExplanationItem.java b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideExplanationItem.java
index 6b8003bc..93fbe59 100644
--- a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideExplanationItem.java
+++ b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideExplanationItem.java
@@ -15,7 +15,9 @@
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
-/** A custom view for an item (icon + text) of a setting explanation for the privacy guide. */
+/**
+ * A custom view for an item (icon + text) of a setting explanation for the privacy guide.
+ */
 public class PrivacyGuideExplanationItem extends LinearLayout {
     public PrivacyGuideExplanationItem(Context context, AttributeSet attrs) {
         super(context, attrs);
diff --git a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideFragment.java b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideFragment.java
new file mode 100644
index 0000000..a6268e6
--- /dev/null
+++ b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideFragment.java
@@ -0,0 +1,143 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.privacy_guide;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.fragment.app.Fragment;
+import androidx.viewpager2.widget.ViewPager2;
+
+import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
+import org.chromium.ui.widget.ButtonCompat;
+
+/**
+ * Fragment containing the Privacy Guide (a walk-through of the most important privacy settings).
+ */
+public class PrivacyGuideFragment extends Fragment {
+    private BottomSheetController mBottomSheetController;
+    private PrivacyGuidePagerAdapter mPagerAdapter;
+    private View mView;
+    private ViewPager2 mViewPager;
+    private ButtonCompat mNextButton;
+    private ButtonCompat mBackButton;
+    private ButtonCompat mFinishButton;
+
+    @Override
+    public void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setHasOptionsMenu(true);
+    }
+
+    @Nullable
+    @Override
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+            @Nullable Bundle savedInstanceState) {
+        modifyAppBar();
+
+        mView = inflater.inflate(R.layout.privacy_guide_fragment, container, false);
+        displayWelcomePage();
+
+        return mView;
+    }
+
+    private void modifyAppBar() {
+        AppCompatActivity settingsActivity = (AppCompatActivity) getActivity();
+        settingsActivity.setTitle(R.string.prefs_privacy_guide_title);
+        settingsActivity.getSupportActionBar().setDisplayHomeAsUpEnabled(false);
+    }
+
+    private void displayWelcomePage() {
+        FrameLayout content = mView.findViewById(R.id.fragment_content);
+        content.removeAllViews();
+        getLayoutInflater().inflate(R.layout.privacy_guide_welcome, content);
+
+        ButtonCompat welcomeButton = (ButtonCompat) mView.findViewById(R.id.start_button);
+        welcomeButton.setOnClickListener((View v) -> displayMainFlow());
+    }
+
+    private void displayMainFlow() {
+        FrameLayout content = mView.findViewById(R.id.fragment_content);
+        content.removeAllViews();
+        getLayoutInflater().inflate(R.layout.privacy_guide_steps, content);
+
+        mViewPager = (ViewPager2) mView.findViewById(R.id.review_viewpager);
+        mPagerAdapter = new PrivacyGuidePagerAdapter(mBottomSheetController);
+        mViewPager.setAdapter(mPagerAdapter);
+        mViewPager.setUserInputEnabled(false);
+
+        mNextButton = (ButtonCompat) mView.findViewById(R.id.next_button);
+        mNextButton.setOnClickListener((View v) -> nextStep());
+
+        mBackButton = (ButtonCompat) mView.findViewById(R.id.back_button);
+        mBackButton.setOnClickListener((View v) -> previousStep());
+
+        mFinishButton = (ButtonCompat) mView.findViewById(R.id.finish_button);
+        mFinishButton.setOnClickListener((View v) -> displayDonePage());
+    }
+
+    private void displayDonePage() {
+        FrameLayout content = mView.findViewById(R.id.fragment_content);
+        content.removeAllViews();
+        getLayoutInflater().inflate(R.layout.privacy_guide_done, content);
+
+        ButtonCompat doneButton = (ButtonCompat) mView.findViewById(R.id.done_button);
+        doneButton.setOnClickListener((View v) -> getActivity().onBackPressed());
+    }
+
+    private void nextStep() {
+        int nextIdx = mViewPager.getCurrentItem() + 1;
+        if (nextIdx < mPagerAdapter.getItemCount()) {
+            mViewPager.setCurrentItem(nextIdx);
+        }
+        mBackButton.setVisibility(View.VISIBLE);
+        if (nextIdx + 1 == mPagerAdapter.getItemCount()) {
+            mNextButton.setVisibility(View.GONE);
+            mFinishButton.setVisibility(View.VISIBLE);
+        }
+    }
+
+    private void previousStep() {
+        mFinishButton.setVisibility(View.GONE);
+        int prevIdx = mViewPager.getCurrentItem() - 1;
+        if (prevIdx >= 0) {
+            mViewPager.setCurrentItem(prevIdx);
+        }
+        mNextButton.setVisibility(View.VISIBLE);
+        if (prevIdx == 0) {
+            mBackButton.setVisibility(View.INVISIBLE);
+        }
+    }
+
+    @Override
+    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
+        super.onCreateOptionsMenu(menu, inflater);
+        menu.clear();
+        inflater.inflate(R.menu.privacy_guide_toolbar_menu, menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
+        if (item.getItemId() == R.id.close_menu_id) {
+            getActivity().onBackPressed();
+            return true;
+        }
+
+        return false;
+    }
+
+    public void setBottomSheetController(BottomSheetController bottomSheetController) {
+        mBottomSheetController = bottomSheetController;
+    }
+}
diff --git a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuidePagerAdapter.java b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuidePagerAdapter.java
index 563e0da..7cf924c 100644
--- a/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuidePagerAdapter.java
+++ b/chrome/browser/privacy_guide/android/java/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuidePagerAdapter.java
@@ -18,7 +18,9 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
-/** Controls the behavior of the ViewPager to navigate between privacy guide steps. */
+/**
+ * Controls the behavior of the ViewPager to navigate between privacy guide steps.
+ */
 public class PrivacyGuidePagerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
     /**
      * The types of views supported. Each view corresponds to a step in the privacy guide.
diff --git a/chrome/browser/privacy_guide/android/javatests/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideFragmentTest.java b/chrome/browser/privacy_guide/android/javatests/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideFragmentTest.java
new file mode 100644
index 0000000..d267700
--- /dev/null
+++ b/chrome/browser/privacy_guide/android/javatests/src/org/chromium/chrome/browser/privacy_guide/PrivacyGuideFragmentTest.java
@@ -0,0 +1,129 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.privacy_guide;
+
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+
+import static org.hamcrest.CoreMatchers.not;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.util.Batch;
+import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.browser.flags.ChromeSwitches;
+import org.chromium.chrome.browser.settings.SettingsActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.ui.test.util.ViewUtils;
+
+/**
+ * Tests {@link PrivacyGuideFragment}
+ */
+@RunWith(ChromeJUnit4ClassRunner.class)
+@Batch(Batch.PER_CLASS)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
+public class PrivacyGuideFragmentTest {
+    @Rule
+    public SettingsActivityTestRule<PrivacyGuideFragment> mSettingsActivityTestRule =
+            new SettingsActivityTestRule<>(PrivacyGuideFragment.class);
+
+    private void launchPrivacyGuide() {
+        mSettingsActivityTestRule.startSettingsActivity();
+        ViewUtils.onViewWaiting(withText(R.string.prefs_privacy_guide_title));
+    }
+
+    private void testButtonVisibility(int buttonTextId, boolean isVisible) {
+        if (isVisible) {
+            onView(withText(buttonTextId)).check(matches(isDisplayed()));
+        } else {
+            onView(withText(buttonTextId)).check(matches(not(isDisplayed())));
+        }
+    }
+
+    private void testButtons(boolean nextVisible, boolean backVisible, boolean finishVisible) {
+        testButtonVisibility(R.string.next, nextVisible);
+        testButtonVisibility(R.string.back, backVisible);
+        testButtonVisibility(R.string.privacy_guide_finish_button, finishVisible);
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"PrivacyGuide"})
+    public void testForwardNavigation() {
+        launchPrivacyGuide();
+        // Welcome page -> MSBB page
+        onView(withText(R.string.privacy_guide_welcome_title)).check(matches(isDisplayed()));
+        onView(withText(R.string.privacy_guide_start_button)).perform(click());
+
+        // MSBB page -> Sync page
+        ViewUtils.waitForView(withText(R.string.url_keyed_anonymized_data_title));
+        testButtons(true, false, false);
+        onView(withText(R.string.next)).perform(click());
+
+        // Sync page -> SB page
+        ViewUtils.waitForView(withText(R.string.privacy_guide_sync_toggle));
+        testButtons(true, true, false);
+        onView(withText(R.string.next)).perform(click());
+
+        // SB page -> Cookies page
+        ViewUtils.waitForView(withText(R.string.privacy_guide_safe_browsing_intro));
+        testButtons(true, true, false);
+        onView(withText(R.string.next)).perform(click());
+
+        // Cookies page -> Complete page
+        ViewUtils.waitForView(withText(R.string.privacy_guide_cookies_intro));
+        testButtons(false, true, true);
+        onView(withText(R.string.privacy_guide_finish_button)).perform(click());
+
+        // Complete page -> EXIT
+        ViewUtils.waitForView(withText(R.string.privacy_guide_done_title));
+        onView(withText(R.string.done)).perform(click());
+    }
+
+    @Test
+    @SmallTest
+    @Feature({"PrivacyGuide"})
+    public void testBackwardNavigation() {
+        launchPrivacyGuide();
+        // Welcome page -> MSBB page
+        onView(withText(R.string.privacy_guide_start_button)).perform(click());
+
+        // MSBB page -> Sync page
+        ViewUtils.waitForView(withText(R.string.url_keyed_anonymized_data_title));
+        onView(withText(R.string.next)).perform(click());
+        // Sync page -> SB page
+        ViewUtils.waitForView(withText(R.string.privacy_guide_sync_toggle));
+        onView(withText(R.string.next)).perform(click());
+        // SB page -> Cookies page
+        ViewUtils.waitForView(withText(R.string.privacy_guide_safe_browsing_intro));
+        onView(withText(R.string.next)).perform(click());
+
+        // SB page <- Cookies page
+        ViewUtils.waitForView(withText(R.string.privacy_guide_cookies_intro));
+        testButtons(false, true, true);
+        onView(withText(R.string.back)).perform(click());
+        // Sync page <- SB page
+        ViewUtils.waitForView(withText(R.string.privacy_guide_safe_browsing_intro));
+        testButtons(true, true, false);
+        onView(withText(R.string.back)).perform(click());
+        // MSBB page <- Sync page
+        ViewUtils.waitForView(withText(R.string.privacy_guide_sync_toggle));
+        testButtons(true, true, false);
+        onView(withText(R.string.back)).perform(click());
+        // MSBB page -> Exit
+        ViewUtils.waitForView(withText(R.string.url_keyed_anonymized_data_title));
+        testButtons(true, false, false);
+        onView(withId(R.id.close_menu_id)).perform(click());
+    }
+}
\ No newline at end of file
diff --git a/chrome/browser/resources/pdf/elements/icons.html b/chrome/browser/resources/pdf/elements/icons.html
index dfb03a5..5f2144d 100644
--- a/chrome/browser/resources/pdf/elements/icons.html
+++ b/chrome/browser/resources/pdf/elements/icons.html
@@ -9,7 +9,6 @@
       <g id="bookmark"><path d="M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2z"></path></g>
       <g id="bookmark-border"><path d="M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2zm0 15l-5-2.18L7 18V5h10v13z"></path></g>
       <g id="check"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"></path></g>
-      <g id="create"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"></path></g>
       <g id="doc-outline"><path d="M0 0h24v24H0z" fill="none"></path><path d="M19 5v14H5V5h14m1.1-2H3.9c-.5 0-.9.4-.9.9v16.2c0 .4.4.9.9.9h16.2c.4 0 .9-.5.9-.9V3.9c0-.5-.5-.9-.9-.9zM11 7h6v2h-6V7zm0 4h6v2h-6v-2zm0 4h6v2h-6zM7 7h2v2H7zm0 4h2v2H7zm0 4h2v2H7z"></path></g>
       <g id="eraser"><path d="M21.41,11.33 L13.04,20 L4.73,20 L2.58,17.86 C1.8,17.08 1.8,15.83 2.58,15.04 L13.62,3.58 C14.4,2.81 15.68,2.81 16.46,3.58 L21.41,8.51 C22.2,9.29 22.2,10.55 21.41,11.33 L21.41,11.33 Z"></path><polygon points="17.26 18 15.26 20 21.96 20 21.96 18"></polygon></g>
       <g id="fit-to-height"><path fill-rule="evenodd" clip-rule="evenodd" d="M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 10l3.01-4.5L15 10H9zm0 4h6l-2.99 4.5L9 14zm-6 5.01h18V4.99H3v14.02z"></path></g>
diff --git a/chrome/browser/resources/pdf/elements/viewer-toolbar.html b/chrome/browser/resources/pdf/elements/viewer-toolbar.html
index 066df497..990e133 100644
--- a/chrome/browser/resources/pdf/elements/viewer-toolbar.html
+++ b/chrome/browser/resources/pdf/elements/viewer-toolbar.html
@@ -246,7 +246,7 @@
   <div id="end">
   <if expr="enable_ink">
     <template is="dom-if" if="[[pdfAnnotationsEnabled]]">
-      <cr-icon-button id="annotate" iron-icon="pdf:create"
+      <cr-icon-button id="annotate" iron-icon="cr:create"
           on-click="onAnnotationClick_"
           aria-label="$i18n{tooltipAnnotate}"
           disabled="[[!annotationsAvailable]]"
diff --git a/chrome/browser/resources/settings/icons.html b/chrome/browser/resources/settings/icons.html
index 00d9ae7..809f977 100644
--- a/chrome/browser/resources/settings/icons.html
+++ b/chrome/browser/resources/settings/icons.html
@@ -108,7 +108,6 @@
       <g id="code"><path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"></path></g>
       <g id="code-off"><path d="M19.17,12l-4.58-4.59L16,6l6,6l-3.59,3.59L17,14.17L19.17,12z M1.39,4.22l4.19,4.19L2,12l6,6l1.41-1.41L4.83,12L7,9.83 l12.78,12.78l1.41-1.41L2.81,2.81L1.39,4.22z"></path></g>
       <g id="content-copy"><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"></path></g>
-      <g id="create"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"></path></g>
       <g id="devices"><path d="M5 6h16V4H5c-1.1 0-2 .9-2 2v11H1v3h11v-3H5V6zm16 2h-6c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h6c.55 0 1-.45 1-1V9c0-.55-.45-1-1-1zm-1 9h-4v-7h4v7z"></path></g>
       <g id="devices-off"><path d="M22 9V19L20 17V10H16V13L14 11V9C14 8.45 14.45 8 15 8H21C21.55 8 22 8.45 22 9ZM21 6V4H7L9 6H21ZM17.2 17L16 15.8L14 13.8L6.2 6L4.33 4.13L2.6 2.4L1.2 3.8L3.06 5.66C3.03 5.77 3 5.88 3 6V17H1V20H12V17H5V7.6L14 16.6V19C14 19.55 14.45 20 15 20H17.4L20.4 23L21.8 21.6L20.2 20L17.2 17Z"></path></g>
       <g id="exit-to-app"><path d="M10.09 15.59L11.5 17l5-5-5-5-1.41 1.41L12.67 11H3v2h9.67l-2.58 2.59zM19 3H5c-1.11 0-2 .9-2 2v4h2V5h14v14H5v-4H3v4c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"></path></g>
diff --git a/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html b/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html
index 5ca35ed5..dbf9275 100644
--- a/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html
+++ b/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html
@@ -106,7 +106,7 @@
                       [[item.userDisplayName]]
                     </div>
                     <div class="user-name">[[item.userName]]</div>
-                    <cr-icon-button iron-icon="settings:create"
+                    <cr-icon-button iron-icon="cr:create"
                         aria-label="$i18n{edit}"
                         class="edit-button"
                         on-click="onUpdateButtonClick_"
diff --git a/chrome/browser/resources/signin/BUILD.gn b/chrome/browser/resources/signin/BUILD.gn
index 86a40d7..197353a1 100644
--- a/chrome/browser/resources/signin/BUILD.gn
+++ b/chrome/browser/resources/signin/BUILD.gn
@@ -81,7 +81,6 @@
       "enterprise_profile_welcome/enterprise_profile_welcome_browser_proxy.ts",
       "profile_customization/profile_customization_browser_proxy.ts",
       "signin_error/signin_error.ts",
-      "signin_icons.ts",
     ]
   }
   if (enable_dice_support) {
diff --git a/chrome/browser/resources/signin/profile_customization/profile_customization_app.html b/chrome/browser/resources/signin/profile_customization/profile_customization_app.html
index c69d79d..0e55911b 100644
--- a/chrome/browser/resources/signin/profile_customization/profile_customization_app.html
+++ b/chrome/browser/resources/signin/profile_customization/profile_customization_app.html
@@ -178,7 +178,7 @@
       </template>
       <template is="dom-if" if="[[isLocalProfileCreation_]]">
         <div class="avatar-badge">
-          <cr-icon-button id="customizeAvatarIcon" iron-icon="signin:create"
+          <cr-icon-button id="customizeAvatarIcon" iron-icon="cr:create"
               on-click="onCustomizeAvatarClick_">
           </cr-icon-button>
         </div>
diff --git a/chrome/browser/resources/signin/profile_customization/profile_customization_app.ts b/chrome/browser/resources/signin/profile_customization/profile_customization_app.ts
index f0ac4381..aaf4b59b 100644
--- a/chrome/browser/resources/signin/profile_customization/profile_customization_app.ts
+++ b/chrome/browser/resources/signin/profile_customization/profile_customization_app.ts
@@ -9,7 +9,6 @@
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 import 'chrome://resources/cr_elements/icons.m.js';
 import './strings.m.js';
-import './signin_icons.js';
 import './signin_shared.css.js';
 import './signin_vars.css.js';
 
diff --git a/chrome/browser/resources/signin/profile_picker/icons.ts b/chrome/browser/resources/signin/profile_picker/icons.ts
index 6d56e02..bb41c08 100644
--- a/chrome/browser/resources/signin/profile_picker/icons.ts
+++ b/chrome/browser/resources/signin/profile_picker/icons.ts
@@ -25,10 +25,6 @@
     <g id="lock" viewBox="0 0 48 48">
       <path d="M0 0h48v48H0z" fill="none"/><path d="M36 16h-2v-4c0-5.52-4.48-10-10-10S14 6.48 14 12v4h-2c-2.21 0-4 1.79-4 4v20c0 2.21 1.79 4 4 4h24c2.21 0 4-1.79 4-4V20c0-2.21-1.79-4-4-4zM24 34c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm6.2-18H17.8v-4c0-3.42 2.78-6.2 6.2-6.2 3.42 0 6.2 2.78 6.2 6.2v4z"/>
     </g>
-
-    <g id="create" viewBox="0 0 24 24">
-      <path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/>
-    </g>
   </defs>
 </svg>`;
 document.head.appendChild(element);
diff --git a/chrome/browser/resources/signin/profile_picker/profile_card_menu.html b/chrome/browser/resources/signin/profile_picker/profile_card_menu.html
index ebf9c77b..2eab9c7 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_card_menu.html
+++ b/chrome/browser/resources/signin/profile_picker/profile_card_menu.html
@@ -148,7 +148,7 @@
 
 <cr-action-menu id="actionMenu" role-description="$i18n{menu}">
   <button class="dropdown-item" on-click="onCustomizeButtonClicked_">
-    <iron-icon icon="profiles:create" aria-hidden="true"></iron-icon>
+    <iron-icon icon="cr:create" aria-hidden="true"></iron-icon>
     $i18n{profileMenuCustomizeText}
   </button>
   <button class="dropdown-item" on-click="onRemoveButtonClicked_">
diff --git a/chrome/browser/resources/signin/profile_picker/profile_card_menu.ts b/chrome/browser/resources/signin/profile_picker/profile_card_menu.ts
index 3d515ce..8bea43a 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_card_menu.ts
+++ b/chrome/browser/resources/signin/profile_picker/profile_card_menu.ts
@@ -10,7 +10,6 @@
 import 'chrome://resources/cr_elements/shared_vars_css.m.js';
 import 'chrome://resources/js/action_link.js';
 import './profile_picker_shared.css.js';
-import './icons.js';
 
 import {CrActionMenuElement} from 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js';
 import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
diff --git a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.html b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.html
index b910e07..fdad2647 100644
--- a/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.html
+++ b/chrome/browser/resources/signin/profile_picker/profile_creation_flow/local_profile_customization.html
@@ -207,7 +207,7 @@
     <img class="avatar" alt="" src$="[[selectedAvatar_.url]]">
     <div id="customizeAvatarEllipse"></div>
     <cr-icon-button id="customizeAvatarIcon"
-        iron-icon="profiles:create" on-click="onCustomizeAvatarClick_"
+        iron-icon="cr:create" on-click="onCustomizeAvatarClick_"
         aria-label="$i18n{localProfileCreationCustomizeAvatarLabel}">
     </cr-icon-button>
   </div>
diff --git a/chrome/browser/resources/signin/signin_icons.ts b/chrome/browser/resources/signin/signin_icons.ts
deleted file mode 100644
index 5a6ef83..0000000
--- a/chrome/browser/resources/signin/signin_icons.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'chrome://resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js';
-
-const element = document.createElement('iron-iconset-svg');
-element.name = 'signin';
-element.innerHTML = `
-<svg>
-  <defs>
-    <g id="create" viewBox="0 0 24 24">
-      <path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/>
-    </g>
-  </defs>
-</svg>`;
-document.head.appendChild(element);
\ No newline at end of file
diff --git a/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.cc b/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.cc
new file mode 100644
index 0000000..f1bc1ad
--- /dev/null
+++ b/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.cc
@@ -0,0 +1,17 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/supervised_user/kids_chrome_management/kids_management_service.h"
+
+#include "components/keyed_service/core/keyed_service.h"
+#include "content/public/browser/browser_context.h"
+
+namespace chrome::kids {
+// Builds the service instance and its local dependencies.
+// The profile dependency is needed to verify the dynamic child account status.
+KeyedService* KidsManagementServiceFactory::BuildServiceInstanceFor(
+    content::BrowserContext* browser_context) const {
+  return new KidsManagementService();
+}
+}  // namespace chrome::kids
diff --git a/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.h b/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.h
new file mode 100644
index 0000000..099503a
--- /dev/null
+++ b/chrome/browser/supervised_user/kids_chrome_management/kids_management_service.h
@@ -0,0 +1,41 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_SUPERVISED_USER_KIDS_CHROME_MANAGEMENT_KIDS_MANAGEMENT_SERVICE_H_
+#define CHROME_BROWSER_SUPERVISED_USER_KIDS_CHROME_MANAGEMENT_KIDS_MANAGEMENT_SERVICE_H_
+
+#include "base/memory/singleton.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+#include "components/keyed_service/core/keyed_service.h"
+#include "content/public/browser/browser_context.h"
+
+namespace chrome::kids {
+
+// A keyed service aggregating services for respective RPCs in
+// KidsManagementAPI.
+class KidsManagementService : public KeyedService {};
+
+// The framework binding for the KidsManagementAPI service.
+class KidsManagementServiceFactory : public BrowserContextKeyedServiceFactory {
+ public:
+  static KidsManagementService* GetForProfile(Profile* profile);
+  static KidsManagementServiceFactory* GetInstance();
+
+  KidsManagementServiceFactory(const KidsManagementServiceFactory&) = delete;
+  KidsManagementServiceFactory& operator=(const KidsManagementServiceFactory&) =
+      delete;
+
+ private:
+  friend struct base::DefaultSingletonTraits<KidsManagementServiceFactory>;
+
+  KidsManagementServiceFactory();
+  ~KidsManagementServiceFactory() override;
+
+  // BrowserContextKeyedServiceFactory:
+  KeyedService* BuildServiceInstanceFor(
+      content::BrowserContext* profile) const override;
+};
+}  // namespace chrome::kids
+
+#endif  // CHROME_BROWSER_SUPERVISED_USER_KIDS_CHROME_MANAGEMENT_KIDS_MANAGEMENT_SERVICE_H_
diff --git a/chrome/browser/ui/android/fast_checkout/BUILD.gn b/chrome/browser/ui/android/fast_checkout/BUILD.gn
index b2d0155..906ddee 100644
--- a/chrome/browser/ui/android/fast_checkout/BUILD.gn
+++ b/chrome/browser/ui/android/fast_checkout/BUILD.gn
@@ -7,8 +7,10 @@
 android_library("java") {
   deps = [
     "//base:jni_java",
+    "//components/autofill/android:autofill_payments_java_resources",
     "//components/autofill/android:main_autofill_java",
     "//components/browser_ui/bottomsheet/android:java",
+    "//components/payments/content/android:java_resources",
     "//url:gurl_java",
   ]
   sources = [
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 e5e1c020..b82f923d 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
@@ -4,14 +4,38 @@
 
 package org.chromium.chrome.browser.ui.fast_checkout.data;
 
+import android.content.Context;
+
 import org.chromium.base.annotations.CalledByNative;
+import org.chromium.chrome.browser.ui.fast_checkout.R;
 import org.chromium.components.autofill.VirtualCardEnrollmentState;
 import org.chromium.url.GURL;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * A credit card, similar to the one used by the PersonalDataManager.
  */
 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 = new HashMap<String, Integer>() {
+        {
+            put("americanExpressCC", R.drawable.amex_card);
+            put("dinersCC", R.drawable.diners_card);
+            put("discoverCC", R.drawable.discover_card);
+            put("eloCC", R.drawable.elo_card);
+            put("genericCC", R.drawable.ic_credit_card_black);
+            put("jcbCC", R.drawable.jcb_card);
+            put("masterCardCC", R.drawable.mc_card);
+            put("mirCC", R.drawable.mir_card);
+            put("troyCC", R.drawable.troy_card);
+            put("unionPayCC", R.drawable.unionpay_card);
+            put("visaCC", R.drawable.visa_card);
+            put("googlePay", R.drawable.google_pay);
+        }
+    };
     private final String mGUID;
     private final String mOrigin;
     private final boolean mIsLocal;
@@ -144,4 +168,19 @@
     public String getProductDescription() {
         return mProductDescription;
     }
+
+    public String getFormattedExpirationDate(Context context) {
+        return getMonth()
+                + context.getResources().getString(R.string.autofill_expiration_date_separator)
+                + getYear();
+    }
+
+    public int getIssuerIconDrawableId() {
+        String issuerIconDrawable = getIssuerIconString();
+        if (sResourceMap.containsKey(issuerIconDrawable)) {
+            return sResourceMap.get(issuerIconDrawable);
+        } else {
+            return R.drawable.ic_credit_card_black;
+        }
+    }
 }
diff --git a/chrome/browser/ui/android/signin/BUILD.gn b/chrome/browser/ui/android/signin/BUILD.gn
index 6a6d411..dc9e4e6 100644
--- a/chrome/browser/ui/android/signin/BUILD.gn
+++ b/chrome/browser/ui/android/signin/BUILD.gn
@@ -214,6 +214,7 @@
     "java/src/org/chromium/chrome/browser/ui/signin/ConfirmSyncDataStateMachineDelegateTest.java",
     "java/src/org/chromium/chrome/browser/ui/signin/SignOutDialogRenderTest.java",
     "java/src/org/chromium/chrome/browser/ui/signin/SignOutDialogTest.java",
+    "java/src/org/chromium/chrome/browser/ui/signin/TangibleSyncCoordinatorTest.java",
     "java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerDialogTest.java",
     "java/src/org/chromium/chrome/browser/ui/signin/fre/FreUMADialogTest.java",
   ]
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SyncConsentFragmentBase.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SyncConsentFragmentBase.java
index d599d00..b50e135 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SyncConsentFragmentBase.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SyncConsentFragmentBase.java
@@ -112,6 +112,10 @@
     // success. Instead, this member should be set to false to give the user a chance of clicking
     // "No, thanks".
     private boolean mIsSigninInProgress;
+    // Set to true when the fragment is launched for add account flow. The value is only checked in
+    // tangible sync flow where the activity would otherwise be terminated if selected account is
+    // not provided.
+    private boolean mIsAccountAdditionInProgress;
     private boolean mCanUseGooglePlayServices;
     private boolean mRecordUndoSignin;
     private boolean mIsSignedInWithoutSync;
@@ -270,8 +274,11 @@
             // If this fragment is being recreated from a saved state there's no need to show
             // account picked or starting AddAccount flow.
             if (signinFlowType == SigninFlowType.CHOOSE_ACCOUNT) {
-                mAccountPickerDialogCoordinator = new AccountPickerDialogCoordinator(
-                        requireContext(), this, mModalDialogManager);
+                // Only show the account picker for the old signin view.
+                if (!showTangibleSyncConsentView()) {
+                    mAccountPickerDialogCoordinator = new AccountPickerDialogCoordinator(
+                            requireContext(), this, mModalDialogManager);
+                }
             } else if (signinFlowType == SigninFlowType.ADD_ACCOUNT) {
                 addAccount();
             }
@@ -652,6 +659,7 @@
 
     @Override
     public void addAccount() {
+        mIsAccountAdditionInProgress = true;
         mAccountManagerFacade.createAddAccountIntent((@Nullable Intent intent) -> {
             if (intent != null) {
                 startActivityForResult(intent, ADD_ACCOUNT_REQUEST_CODE);
@@ -660,23 +668,36 @@
 
             // AccountManagerFacade couldn't create intent, use SigninUtils to open settings
             // instead.
+            // TODO(https://crbug.com/1351315): Add histogram to check if this flow is triggered
+            // in user devices.
             SigninUtils.openSettingsForAllAccounts(getActivity());
+            mIsAccountAdditionInProgress = false;
+            if (showTangibleSyncConsentView()) {
+                // For tangible sync flow this fragment should not be shown in the absence of a
+                // selected account when add account intent can't be created.
+                getActivity().finish();
+            }
         });
+        // mAccountPickerDialogCoordinator could be null here as this method may be called without
+        // showing the account picker.
+        if (mAccountPickerDialogCoordinator != null) {
+            mAccountPickerDialogCoordinator.dismissDialog();
+        }
     }
 
     @Override
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (requestCode == ADD_ACCOUNT_REQUEST_CODE && resultCode == Activity.RESULT_OK
-                && data != null) {
-            String addedAccountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
-            if (addedAccountName == null) return;
-
-            // Found the account name, dismiss the dialog if it is shown
-            if (mAccountPickerDialogCoordinator != null) {
-                mAccountPickerDialogCoordinator.dismissDialog();
+        if (requestCode == ADD_ACCOUNT_REQUEST_CODE) {
+            if (resultCode == Activity.RESULT_OK && data != null) {
+                String addedAccountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
+                if (addedAccountName != null) {
+                    mSelectedAccountName = addedAccountName;
+                }
             }
-
-            mSelectedAccountName = addedAccountName;
+            if (showTangibleSyncConsentView()) {
+                mIsAccountAdditionInProgress = false;
+                mAccountManagerFacade.getAccounts().then(this::updateAccounts);
+            }
         }
     }
 
@@ -708,10 +729,18 @@
             return;
         }
         if (mSyncConsentView != null) {
+            if (mIsAccountAdditionInProgress) {
+                // Wait for the account addition to finish.
+                return;
+            }
             final boolean selectedAccountExists = mSelectedAccountName != null
                     && AccountUtils.findAccountByName(accounts, mSelectedAccountName) != null;
-            if (!selectedAccountExists) {
-                getActivity().finish();
+            if (selectedAccountExists) {
+                selectAccount(mSelectedAccountName);
+            } else {
+                // Tangible sync consent view can't be shown without a selected account. Treat
+                // removal of selected account in the background as a sync refused event;
+                onSyncRefused();
             }
             return;
         }
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/TangibleSyncCoordinator.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/TangibleSyncCoordinator.java
index 48d82dec..9b4a620 100644
--- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/TangibleSyncCoordinator.java
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/TangibleSyncCoordinator.java
@@ -50,17 +50,17 @@
     /** Implements {@link AccountPickerCoordinator.Listener}. */
     @Override
     public void onAccountSelected(String accountName) {
-        mSyncConsentActivityLauncher.launchActivityForPromoDefaultFlow(
+        mSyncConsentActivityLauncher.launchActivityForPromoChooseAccountFlow(
                 mContext, mAccessPoint, accountName);
         mAccountPickerDialogCoordinator.dismissDialog();
     }
 
     /**
      * Implements {@link AccountPickerCoordinator.Listener}.
-     * TODO(crbug/1322421): Implement add account flow for tangible sync.
      */
     @Override
     public void addAccount() {
+        mSyncConsentActivityLauncher.launchActivityForPromoAddAccountFlow(mContext, mAccessPoint);
         mAccountPickerDialogCoordinator.dismissDialog();
     }
 }
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/TangibleSyncCoordinatorTest.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/TangibleSyncCoordinatorTest.java
new file mode 100644
index 0000000..c64526d9f
--- /dev/null
+++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/TangibleSyncCoordinatorTest.java
@@ -0,0 +1,95 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.ui.signin;
+
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.RootMatchers.isDialog;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+
+import static org.mockito.Mockito.verify;
+
+import androidx.test.filters.MediumTest;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.mockito.quality.Strictness;
+
+import org.chromium.base.test.BaseActivityTestRule;
+import org.chromium.base.test.util.Batch;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule;
+import org.chromium.components.signin.metrics.SigninAccessPoint;
+import org.chromium.content_public.browser.test.util.TestThreadUtils;
+import org.chromium.ui.test.util.BlankUiTestActivity;
+
+@RunWith(ChromeJUnit4ClassRunner.class)
+@Batch(Batch.PER_CLASS)
+public class TangibleSyncCoordinatorTest {
+    @ClassRule
+    public static final BaseActivityTestRule<BlankUiTestActivity> sActivityTestRule =
+            new BaseActivityTestRule<>(BlankUiTestActivity.class);
+
+    @Rule
+    public final AccountManagerTestRule mAccountManagerTestRule = new AccountManagerTestRule();
+
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
+
+    @Mock
+    private SyncConsentActivityLauncher mSyncConsentActivityLauncher;
+
+    @BeforeClass
+    public static void setupSuite() {
+        sActivityTestRule.launchActivity(null);
+    }
+
+    @Before
+    public void setUp() {
+        mAccountManagerTestRule.addAccount(AccountManagerTestRule.TEST_ACCOUNT_EMAIL);
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            TangibleSyncCoordinator.start(sActivityTestRule.getActivity(),
+                    sActivityTestRule.getActivity().getModalDialogManager(),
+                    mSyncConsentActivityLauncher, SigninAccessPoint.SETTINGS);
+        });
+    }
+
+    @Test
+    @MediumTest
+    public void testAddAccount() {
+        onView(withText(R.string.signin_account_picker_dialog_title))
+                .inRoot(isDialog())
+                .check(matches(isDisplayed()));
+        onView(withText(R.string.signin_add_account_to_device)).inRoot(isDialog()).perform(click());
+
+        verify(mSyncConsentActivityLauncher)
+                .launchActivityForPromoAddAccountFlow(
+                        sActivityTestRule.getActivity(), SigninAccessPoint.SETTINGS);
+    }
+
+    @Test
+    @MediumTest
+    public void testSelectAccount() {
+        onView(withText(R.string.signin_account_picker_dialog_title))
+                .inRoot(isDialog())
+                .check(matches(isDisplayed()));
+        onView(withText(AccountManagerTestRule.TEST_ACCOUNT_EMAIL))
+                .inRoot(isDialog())
+                .perform(click());
+
+        verify(mSyncConsentActivityLauncher)
+                .launchActivityForPromoChooseAccountFlow(sActivityTestRule.getActivity(),
+                        SigninAccessPoint.SETTINGS, AccountManagerTestRule.TEST_ACCOUNT_EMAIL);
+    }
+}
\ No newline at end of file
diff --git a/chrome/browser/ui/views/download/bubble/download_bubble_row_view.cc b/chrome/browser/ui/views/download/bubble/download_bubble_row_view.cc
index c80b90a4..ada56943 100644
--- a/chrome/browser/ui/views/download/bubble/download_bubble_row_view.cc
+++ b/chrome/browser/ui/views/download/bubble/download_bubble_row_view.cc
@@ -125,7 +125,8 @@
 
   // If either of mode or state changes, or if it is the initial setup,
   // we might need to change UI.
-  ui_info_ = model_->GetBubbleUIInfo();
+  ui_info_ = model_->GetBubbleUIInfo(
+      download::IsDownloadBubbleV2Enabled(browser_->profile()));
   return true;
 }
 
diff --git a/chrome/browser/ui/views/download/bubble/download_bubble_security_view.cc b/chrome/browser/ui/views/download/bubble/download_bubble_security_view.cc
index 1ed7400..443b69d 100644
--- a/chrome/browser/ui/views/download/bubble/download_bubble_security_view.cc
+++ b/chrome/browser/ui/views/download/bubble/download_bubble_security_view.cc
@@ -45,14 +45,14 @@
 enum class DownloadBubbleSubpageAction {
   kShown = 0,
   kShownCheckbox = 1,
-  kShownFirstButton = 2,
-  kShownSecondButton = 3,
+  kShownSecondaryButton = 2,
+  kShownPrimaryButton = 3,
   kPressedBackButton = 4,
   kClosedSubpage = 5,
   kClickedCheckbox = 6,
-  kPressedFirstButton = 7,
-  kPressedSecondButton = 8,
-  kMaxValue = kPressedSecondButton
+  kPressedSecondaryButton = 7,
+  kPressedPrimaryButton = 8,
+  kMaxValue = kPressedPrimaryButton
 };
 const char kSubpageActionHistogram[] = "Download.Bubble.SubpageAction";
 }  // namespace
@@ -123,7 +123,8 @@
 }
 
 void DownloadBubbleSecurityView::OnCheckboxClicked() {
-  first_button_->SetEnabled(checkbox_->GetChecked());
+  DCHECK(secondary_button_);
+  secondary_button_->SetEnabled(checkbox_->GetChecked());
   base::UmaHistogramEnumeration(kSubpageActionHistogram,
                                 DownloadBubbleSubpageAction::kClickedCheckbox);
 }
@@ -221,8 +222,8 @@
 
 void DownloadBubbleSecurityView::ProcessButtonClick(
     DownloadCommands::Command command,
-    bool is_first_button) {
-  RecordWarningActionTime(is_first_button);
+    bool is_secondary_button) {
+  RecordWarningActionTime(is_secondary_button);
   // First open primary dialog, and then execute the command. If a deletion
   // happens leading to closure of the bubble, it will be called after primary
   // dialog is opened.
@@ -231,8 +232,8 @@
                                                  command);
   base::UmaHistogramEnumeration(
       kSubpageActionHistogram,
-      is_first_button ? DownloadBubbleSubpageAction::kPressedFirstButton
-                      : DownloadBubbleSubpageAction::kPressedSecondButton);
+      is_secondary_button ? DownloadBubbleSubpageAction::kPressedSecondaryButton
+                          : DownloadBubbleSubpageAction::kPressedPrimaryButton);
 }
 
 views::MdTextButton* DownloadBubbleSecurityView::GetButtonForCommand(
@@ -242,54 +243,62 @@
                                                   : nullptr;
 }
 
+void DownloadBubbleSecurityView::UpdateButton(
+    DownloadUIModel::BubbleUIInfo::SubpageButton button_info,
+    bool is_secondary_button,
+    bool has_checkbox,
+    SkColor color) {
+  views::MdTextButton* button = GetButtonForCommand(button_info.command);
+  button->SetCallback(base::BindRepeating(
+      &DownloadBubbleSecurityView::ProcessButtonClick, base::Unretained(this),
+      button_info.command, is_secondary_button));
+  button->SetText(button_info.label);
+  button->SetProminent(button_info.is_prominent);
+  button->SetVisible(true);
+  if (is_secondary_button) {
+    button->SetEnabledTextColors(color);
+    button->SetEnabled(!has_checkbox);
+    secondary_button_ = button;
+  }
+  base::UmaHistogramEnumeration(
+      kSubpageActionHistogram,
+      is_secondary_button ? DownloadBubbleSubpageAction::kShownSecondaryButton
+                          : DownloadBubbleSubpageAction::kShownPrimaryButton);
+}
+
 void DownloadBubbleSecurityView::UpdateButtons() {
   discard_button_->SetVisible(false);
   keep_button_->SetVisible(false);
   deep_scan_button_->SetVisible(false);
   bypass_deep_scan_button_->SetVisible(false);
+  secondary_button_ = nullptr;
   DownloadUIModel::BubbleUIInfo& ui_info = download_row_view_->ui_info();
 
   if (ui_info.subpage_buttons.size() > 0) {
-    first_button_ = GetButtonForCommand(ui_info.subpage_buttons[0].command);
-    first_button_->SetCallback(base::BindRepeating(
-        &DownloadBubbleSecurityView::ProcessButtonClick, base::Unretained(this),
-        ui_info.subpage_buttons[0].command,
-        /*is_first_button=*/true));
-    first_button_->SetText(ui_info.subpage_buttons[0].label);
-    first_button_->SetProminent(ui_info.subpage_buttons[0].is_prominent);
-    first_button_->SetEnabledTextColors(GetColorProvider()->GetColor(
-        download_row_view_->ui_info().secondary_color));
-    first_button_->SetEnabled(!ui_info.has_checkbox);
-    first_button_->SetVisible(true);
-    base::UmaHistogramEnumeration(
-        kSubpageActionHistogram,
-        DownloadBubbleSubpageAction::kShownFirstButton);
+    UpdateButton(ui_info.subpage_buttons[0], /*is_secondary_button=*/false,
+                 ui_info.has_checkbox,
+                 GetColorProvider()->GetColor(
+                     download_row_view_->ui_info().secondary_color));
   }
+
   if (ui_info.subpage_buttons.size() > 1) {
-    views::MdTextButton* second_button =
-        GetButtonForCommand(ui_info.subpage_buttons[1].command);
-    second_button->SetCallback(base::BindRepeating(
-        &DownloadBubbleSecurityView::ProcessButtonClick, base::Unretained(this),
-        ui_info.subpage_buttons[1].command,
-        /*is_first_button=*/false));
-    second_button->SetText(ui_info.subpage_buttons[1].label);
-    second_button->SetVisible(true);
-    second_button->SetProminent(ui_info.subpage_buttons[1].is_prominent);
-    base::UmaHistogramEnumeration(
-        kSubpageActionHistogram,
-        DownloadBubbleSubpageAction::kShownSecondButton);
+    UpdateButton(ui_info.subpage_buttons[1], /*is_secondary_button=*/true,
+                 ui_info.has_checkbox,
+                 GetColorProvider()->GetColor(
+                     download_row_view_->ui_info().secondary_color));
   }
 }
 
-void DownloadBubbleSecurityView::RecordWarningActionTime(bool is_first_button) {
+void DownloadBubbleSecurityView::RecordWarningActionTime(
+    bool is_secondary_button) {
   DCHECK(warning_time_.has_value());
   // Example Histogram
-  // Download.Bubble.Subpage.DangerousFile.FirstButtonActionTime
+  // Download.Bubble.Subpage.DangerousFile.SecondaryButtonActionTime
   std::string histogram = base::StrCat(
       {"Download.Bubble.Subpage.",
        download::GetDownloadDangerTypeString(
            download_row_view_->model()->GetDownloadItem()->GetDangerType()),
-       ".", is_first_button ? "First" : "Second", "ButtonActionTime"});
+       ".", is_secondary_button ? "Secondary" : "Primary", "ButtonActionTime"});
   base::UmaHistogramMediumTimes(histogram,
                                 base::Time::Now() - (*warning_time_));
   warning_time_ = absl::nullopt;
diff --git a/chrome/browser/ui/views/download/bubble/download_bubble_security_view.h b/chrome/browser/ui/views/download/bubble/download_bubble_security_view.h
index e381a13d5..7afbbf5 100644
--- a/chrome/browser/ui/views/download/bubble/download_bubble_security_view.h
+++ b/chrome/browser/ui/views/download/bubble/download_bubble_security_view.h
@@ -55,18 +55,27 @@
   void OnCheckboxClicked();
   void UpdateIconAndText();
   void AddIconAndText();
+  // Updates the subpage button. Setting initial state and color for enabled
+  // state, if it is a secondary button.
+  void UpdateButton(DownloadUIModel::BubbleUIInfo::SubpageButton button,
+                    bool is_secondary_button,
+                    bool has_checkbox,
+                    SkColor color);
   void UpdateButtons();
   void AddButtons();
 
+  // |is_secondary_button| checks if the command/action originated from the
+  // secondary button.
   void ProcessButtonClick(DownloadCommands::Command command,
-                          bool is_first_button);
+                          bool is_secondary_button);
   views::MdTextButton* GetButtonForCommand(DownloadCommands::Command command);
-  void RecordWarningActionTime(bool is_first_button);
+  void RecordWarningActionTime(bool is_secondary_button);
 
   raw_ptr<DownloadBubbleRowView> download_row_view_;
   raw_ptr<DownloadBubbleUIController> bubble_controller_ = nullptr;
   raw_ptr<DownloadBubbleNavigationHandler> navigation_handler_ = nullptr;
-  raw_ptr<views::MdTextButton> first_button_ = nullptr;
+  // The secondary button is the one that may be protected by the checkbox.
+  raw_ptr<views::MdTextButton> secondary_button_ = nullptr;
   raw_ptr<views::Checkbox> checkbox_ = nullptr;
   raw_ptr<views::Label> title_ = nullptr;
   raw_ptr<views::ImageView> icon_ = nullptr;
diff --git a/chrome/browser/ui/views/frame/webui_tab_strip_interactive_uitest.cc b/chrome/browser/ui/views/frame/webui_tab_strip_interactive_uitest.cc
index 2564e97..f47c2f1 100644
--- a/chrome/browser/ui/views/frame/webui_tab_strip_interactive_uitest.cc
+++ b/chrome/browser/ui/views/frame/webui_tab_strip_interactive_uitest.cc
@@ -230,7 +230,14 @@
 //
 // This sequence of events would crash without the associated bugfix. More
 // detail is provided in the actual test sequence.
-IN_PROC_BROWSER_TEST_F(WebUITabStripInteractiveTest, CloseTabDuringDrag) {
+// TODO(crbug.com/1352040): Fix consistent failures.
+#if BUILDFLAG(IS_LINUX) && \
+    (defined(THREAD_SANITIZER) || defined(THREAD_SANITIZER))
+#define MAYBE_CloseTabDuringDrag DISABLED_CloseTabDuringDrag
+#else
+#define MAYBE_CloseTabDuringDrag CloseTabDuringDrag
+#endif
+IN_PROC_BROWSER_TEST_F(WebUITabStripInteractiveTest, MAYBE_CloseTabDuringDrag) {
   // Add a second tab and set up an object to instrument that tab.
   ASSERT_TRUE(AddTabAtIndex(-1, GURL("about:blank"), ui::PAGE_TRANSITION_LINK));
   DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kSecondTabElementId);
diff --git a/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc b/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc
index c5da348..1f3424a 100644
--- a/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc
@@ -34,6 +34,9 @@
 
 #if BUILDFLAG(IS_CHROMEOS)
 #include "chrome/browser/web_applications/web_app_utils.h"
+#include "components/infobars/content/content_infobar_manager.h"
+#include "components/infobars/core/infobar.h"
+#include "components/infobars/core/infobar_delegate.h"
 #include "components/services/app_service/public/cpp/features.h"
 #include "components/services/app_service/public/cpp/preferred_apps_test_util.h"
 #endif
@@ -447,3 +450,72 @@
                   ->app_icon()
                   .IsEmpty());
 }
+
+#if BUILDFLAG(IS_CHROMEOS)
+// Test fixture class which shows the supported links infobar when opening an
+// app through the intent picker.
+class IntentChipWithInfoBarBrowserTest : public IntentChipButtonBrowserTest {
+ public:
+  IntentChipWithInfoBarBrowserTest() {
+    feature_list_.InitWithFeatures(
+        /*enabled_features=*/{apps::features::kIntentChipSkipsPicker,
+                              apps::features::kLinkCapturingInfoBar},
+        /*disabled_features=*/{});
+  }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(IntentChipWithInfoBarBrowserTest,
+                       ShowsInfoBarOnAppOpen) {
+  InstallTestWebApp();
+
+  const GURL in_scope_url =
+      https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath());
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), in_scope_url));
+
+  EXPECT_TRUE(GetIntentChip()->GetVisible());
+
+  ClickIntentChip();
+
+  Browser* app_browser = BrowserList::GetInstance()->GetLastActive();
+  EXPECT_TRUE(web_app::AppBrowserController::IsForWebApp(app_browser,
+                                                         test_web_app_id()));
+  auto* infobar_manager = infobars::ContentInfoBarManager::FromWebContents(
+      app_browser->tab_strip_model()->GetActiveWebContents());
+  ASSERT_EQ(infobar_manager->infobar_count(), 1u);
+  ASSERT_EQ(
+      infobar_manager->infobar_at(0)->delegate()->GetIdentifier(),
+      infobars::InfoBarDelegate::SUPPORTED_LINKS_INFOBAR_DELEGATE_CHROMEOS);
+}
+
+// Test fixture class which automatically displays the intent picker bubble when
+// a link is clicked to a page with an installed app.
+class IntentChipWithAutoDisplayBrowserTest
+    : public IntentChipButtonBrowserTest {
+ private:
+  base::test::ScopedFeatureList feature_list_{
+      apps::features::kLinkCapturingAutoDisplayIntentPicker};
+};
+
+IN_PROC_BROWSER_TEST_F(IntentChipWithAutoDisplayBrowserTest,
+                       ShowsIntentPickerOnNavigation) {
+  InstallTestWebApp();
+
+  const GURL in_scope_url =
+      https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath());
+
+  NavigateToLaunchingPage(browser());
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  views::NamedWidgetShownWaiter waiter(views::test::AnyWidgetTestPasskey{},
+                                       IntentPickerBubbleView::kViewClassName);
+
+  ClickLinkAndWait(web_contents, in_scope_url, LinkTarget::SELF, "");
+
+  waiter.WaitIfNeededAndGet();
+  ASSERT_TRUE(IntentPickerBubbleView::intent_picker_bubble());
+}
+#endif  // BUILDFLAG(IS_CHROMEOS)
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc
index 3f74e43..400e34f0 100644
--- a/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_browsertest.cc
@@ -33,6 +33,7 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/content_settings/core/common/content_settings_types.h"
 #include "components/optimization_guide/core/optimization_guide_switches.h"
+#include "components/page_info/core/about_this_site_service.h"
 #include "components/page_info/core/about_this_site_validation.h"
 #include "components/page_info/core/features.h"
 #include "components/page_info/core/proto/about_this_site_metadata.pb.h"
@@ -69,6 +70,8 @@
 
 using AboutThisSiteStatus =
     page_info::about_this_site_validation::AboutThisSiteStatus;
+using AboutThisSiteInteraction =
+    page_info::AboutThisSiteService::AboutThisSiteInteraction;
 
 namespace {
 
@@ -148,19 +151,6 @@
       url, optimization_guide::proto::ABOUT_THIS_SITE, optimization_metadata);
 }
 
-page_info::proto::SiteInfo CreateValidSiteInfo() {
-  page_info::proto::SiteInfo site_info;
-  auto* description = site_info.mutable_description();
-  description->set_description(
-      "A domain used in illustrative examples in documents");
-  description->set_lang("en_US");
-  description->set_name("Example");
-  description->mutable_source()->set_url("https://example.com");
-  description->mutable_source()->set_label("Example source");
-
-  return site_info;
-}
-
 }  // namespace
 
 class PageInfoBubbleViewBrowserTest : public InProcessBrowserTest {
@@ -742,9 +732,12 @@
 class PageInfoBubbleViewAboutThisSiteBrowserTest : public InProcessBrowserTest {
  public:
   PageInfoBubbleViewAboutThisSiteBrowserTest() {
-    feature_list.InitWithFeatures({page_info::kPageInfoAboutThisSiteEn,
-                                   page_info::kPageInfoAboutThisSiteNonEn},
-                                  {});
+    feature_list.InitWithFeatures(
+        {page_info::kPageInfoAboutThisSiteEn,
+         page_info::kPageInfoAboutThisSiteNonEn,
+         page_info::kPageInfoAboutThisSiteMoreInfo,
+         page_info::kPageInfoAboutThisSiteDescriptionPlaceholder},
+        {});
   }
 
   void SetUp() override {
@@ -764,6 +757,23 @@
                           kDisableCheckingUserPermissionsForTesting);
   }
 
+  page_info::proto::SiteInfo CreateValidSiteInfo() {
+    page_info::proto::SiteInfo site_info;
+    auto* description = site_info.mutable_description();
+    description->set_description(
+        "A domain used in illustrative examples in documents");
+    description->set_lang("en_US");
+    description->set_name("Example");
+    description->mutable_source()->set_url("https://example.com");
+    description->mutable_source()->set_label("Example source");
+    site_info.mutable_more_about()->set_url(
+        https_server_.GetURL("a.test", "/title2.html").spec());
+    EXPECT_EQ(
+        page_info::about_this_site_validation::ValidateSiteInfo(site_info),
+        AboutThisSiteStatus::kValid);
+    return site_info;
+  }
+
  protected:
   net::EmbeddedTestServer https_server_{net::EmbeddedTestServer::TYPE_HTTPS};
 
@@ -803,6 +813,64 @@
 }
 
 IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewAboutThisSiteBrowserTest,
+                       AboutThisSiteInteraction) {
+  ukm::TestAutoSetUkmRecorder ukm_recorder;
+  base::HistogramTester histograms;
+
+  auto url = https_server_.GetURL("a.test", "/title1.html");
+  AddHintForTesting(browser(), url, CreateValidSiteInfo());
+
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
+  OpenPageInfoBubble(browser());
+
+  auto* page_info = PageInfoBubbleView::GetPageInfoBubbleForTesting();
+  views::View* button = page_info->GetViewByID(
+      PageInfoViewFactory::VIEW_ID_PAGE_INFO_ABOUT_THIS_SITE_BUTTON);
+  ASSERT_TRUE(button);
+
+  histograms.ExpectUniqueSample("Security.PageInfo.AboutThisSiteInteraction",
+                                AboutThisSiteInteraction::kShownWithDescription,
+                                1);
+
+  PerformMouseClickOnView(button);
+  histograms.ExpectTotalCount("Security.PageInfo.AboutThisSiteInteraction", 2);
+  histograms.ExpectBucketCount(
+      "Security.PageInfo.AboutThisSiteInteraction",
+      AboutThisSiteInteraction::kClickedWithDescription, 1);
+}
+
+IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewAboutThisSiteBrowserTest,
+                       AboutThisSiteInteractionWithoutDescription) {
+  ukm::TestAutoSetUkmRecorder ukm_recorder;
+  base::HistogramTester histograms;
+
+  auto url = https_server_.GetURL("a.test", "/title1.html");
+  auto site_info = CreateValidSiteInfo();
+  site_info.clear_description();
+  EXPECT_EQ(page_info::about_this_site_validation::ValidateSiteInfo(site_info),
+            AboutThisSiteStatus::kValid);
+  AddHintForTesting(browser(), url, site_info);
+
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
+  OpenPageInfoBubble(browser());
+
+  auto* page_info = PageInfoBubbleView::GetPageInfoBubbleForTesting();
+  views::View* button = page_info->GetViewByID(
+      PageInfoViewFactory::VIEW_ID_PAGE_INFO_ABOUT_THIS_SITE_BUTTON);
+  ASSERT_TRUE(button);
+
+  histograms.ExpectUniqueSample(
+      "Security.PageInfo.AboutThisSiteInteraction",
+      AboutThisSiteInteraction::kShownWithoutDescription, 1);
+
+  PerformMouseClickOnView(button);
+  histograms.ExpectTotalCount("Security.PageInfo.AboutThisSiteInteraction", 2);
+  histograms.ExpectBucketCount(
+      "Security.PageInfo.AboutThisSiteInteraction",
+      AboutThisSiteInteraction::kClickedWithoutDescription, 1);
+}
+
+IN_PROC_BROWSER_TEST_F(PageInfoBubbleViewAboutThisSiteBrowserTest,
                        AboutThisSiteNotValid) {
   ukm::TestAutoSetUkmRecorder ukm_recorder;
   base::HistogramTester histograms;
diff --git a/chrome/browser/ui/views/page_info/page_info_main_view.cc b/chrome/browser/ui/views/page_info/page_info_main_view.cc
index 159740f..b753db83 100644
--- a/chrome/browser/ui/views/page_info/page_info_main_view.cc
+++ b/chrome/browser/ui/views/page_info/page_info_main_view.cc
@@ -24,6 +24,7 @@
 #include "chrome/browser/ui/views/page_info/permission_toggle_row_view.h"
 #include "chrome/browser/vr/vr_tab_helper.h"
 #include "chrome/common/url_constants.h"
+#include "components/page_info/core/about_this_site_service.h"
 #include "components/page_info/core/features.h"
 #include "components/page_info/page_info_ui_delegate.h"
 #include "components/permissions/permission_util.h"
@@ -576,28 +577,43 @@
   PageInfoHoverButton* about_this_site_button = nullptr;
 
   if (base::FeatureList::IsEnabled(page_info::kPageInfoAboutThisSiteMoreInfo)) {
+    const auto& description =
+        info.has_description()
+            ? base::UTF8ToUTF16(info.description().description())
+            : l10n_util::GetStringUTF16(
+                  IDS_PAGE_INFO_ABOUT_THIS_PAGE_DESCRIPTION_PLACEHOLDER);
+
     about_this_site_button = about_this_site_section->AddChildView(
         std::make_unique<PageInfoHoverButton>(
             base::BindRepeating(
                 [](PageInfoMainView* view, GURL more_info_url,
-                   const ui::Event& event) {
+                   bool has_description, const ui::Event& event) {
+                  page_info::AboutThisSiteService::OnAboutThisSiteRowClicked(
+                      has_description);
                   view->ui_delegate_->OpenMoreAboutThisPageUrl(more_info_url,
                                                                event);
                   view->GetWidget()->Close();
                 },
-                this, GURL(info.more_about().url())),
+                this, GURL(info.more_about().url()), info.has_description()),
             PageInfoViewFactory::GetAboutThisPageIcon(),
             IDS_PAGE_INFO_ABOUT_THIS_PAGE_TITLE, std::u16string(),
             PageInfoViewFactory::VIEW_ID_PAGE_INFO_ABOUT_THIS_SITE_BUTTON,
             l10n_util::GetStringUTF16(IDS_PAGE_INFO_ABOUT_THIS_PAGE_TOOLTIP),
-            base::UTF8ToUTF16(info.description().description()),
-            PageInfoViewFactory::GetLaunchIcon()));
+            description, PageInfoViewFactory::GetLaunchIcon()));
   } else {
+    // The kPageInfoAboutThisSiteDescriptionPlaceholder feature must only be
+    // enabled together with kPageInfoAboutThisSiteMoreInfo
+    DCHECK(info.has_description());
     about_this_site_button = about_this_site_section->AddChildView(
         std::make_unique<PageInfoHoverButton>(
             base::BindRepeating(
-                &PageInfoNavigationHandler::OpenAboutThisSitePage,
-                base::Unretained(navigation_handler_), info),
+                [](PageInfoMainView* view,
+                   const page_info::proto::SiteInfo& info) {
+                  page_info::AboutThisSiteService::OnAboutThisSiteRowClicked(
+                      info.has_description());
+                  view->navigation_handler_->OpenAboutThisSitePage(info);
+                },
+                this, info),
             PageInfoViewFactory::GetAboutThisSiteIcon(),
             IDS_PAGE_INFO_ABOUT_THIS_SITE_HEADER, std::u16string(),
             PageInfoViewFactory::VIEW_ID_PAGE_INFO_ABOUT_THIS_SITE_BUTTON,
diff --git a/chrome/browser/ui/webui/certificate_provisioning_ui_handler_unittest.cc b/chrome/browser/ui/webui/certificate_provisioning_ui_handler_unittest.cc
index a86bba6..e17f359 100644
--- a/chrome/browser/ui/webui/certificate_provisioning_ui_handler_unittest.cc
+++ b/chrome/browser/ui/webui/certificate_provisioning_ui_handler_unittest.cc
@@ -198,9 +198,9 @@
     content::TestWebUIListenerObserver result_waiter(
         &web_ui_, "certificate-provisioning-processes-changed");
 
-    base::ListValue args;
+    base::Value::List args;
     web_ui_.HandleReceivedMessage("refreshCertificateProvisioningProcessses",
-                                  &args);
+                                  args);
 
     result_waiter.Wait();
     ASSERT_NO_FATAL_FAILURE(ExtractCertProvisioningProcesses(
diff --git a/chrome/browser/ui/webui/chromeos/edu_coexistence/edu_coexistence_login_handler_browsertest.cc b/chrome/browser/ui/webui/chromeos/edu_coexistence/edu_coexistence_login_handler_browsertest.cc
index 6f25e17..ca413442 100644
--- a/chrome/browser/ui/webui/chromeos/edu_coexistence/edu_coexistence_login_handler_browsertest.cc
+++ b/chrome/browser/ui/webui/chromeos/edu_coexistence/edu_coexistence_login_handler_browsertest.cc
@@ -121,9 +121,9 @@
 
   ExpectEduCoexistenceState(EduCoexistenceStateTracker::FlowResult::kLaunched);
 
-  base::ListValue list_args;
+  base::Value::List list_args;
   list_args.Append(kCallbackId);
-  web_ui()->HandleReceivedMessage("initializeEduArgs", &list_args);
+  web_ui()->HandleReceivedMessage("initializeEduArgs", list_args);
   SimulateAccessTokenFetched(handler.get());
 
   EXPECT_EQ(web_ui()->call_data().size(), 1u);
@@ -144,10 +144,10 @@
                        ErrorCallsFromWebUI) {
   std::unique_ptr<EduCoexistenceLoginHandler> handler = SetUpHandler();
 
-  base::ListValue call_args;
+  base::Value::List call_args;
   call_args.Append("error message 1");
   call_args.Append("error message 2");
-  web_ui()->HandleReceivedMessage("error", &call_args);
+  web_ui()->HandleReceivedMessage("error", call_args);
 
   EXPECT_TRUE(handler->in_error_state());
 
@@ -166,9 +166,9 @@
   // C++ handler.
   EXPECT_EQ(web_ui()->call_data().size(), 0u);
 
-  base::ListValue call_args;
+  base::Value::List call_args;
   call_args.Append("coexistence-data-init");
-  web_ui()->HandleReceivedMessage("initializeEduArgs", &call_args);
+  web_ui()->HandleReceivedMessage("initializeEduArgs", call_args);
 
   EXPECT_EQ(web_ui()->call_data().size(), 1u);
   EXPECT_EQ(web_ui()->call_data()[0]->function_name(),
@@ -193,15 +193,15 @@
 
   SimulateAccessTokenFetched(handler.get());
 
-  base::ListValue call_args;
+  base::Value::List call_args;
   call_args.Append(FakeGaiaMixin::kFakeUserEmail);
   call_args.Append(kToSVersion);
 
-  base::ListValue list_args;
+  base::Value::List list_args;
   list_args.Append(kConsentLoggedCallback);
   list_args.Append(std::move(call_args));
 
-  web_ui()->HandleReceivedMessage("consentLogged", &list_args);
+  web_ui()->HandleReceivedMessage("consentLogged", list_args);
 
   const EduCoexistenceStateTracker::FlowState* tracker =
       EduCoexistenceStateTracker::Get()->GetInfoForWebUIForTest(web_ui());
diff --git a/chrome/browser/ui/webui/constrained_web_dialog_ui_unittest.cc b/chrome/browser/ui/webui/constrained_web_dialog_ui_unittest.cc
index 8e091fc..fd6eb95 100644
--- a/chrome/browser/ui/webui/constrained_web_dialog_ui_unittest.cc
+++ b/chrome/browser/ui/webui/constrained_web_dialog_ui_unittest.cc
@@ -138,9 +138,8 @@
         ASSERT_EQ(json_retval, "");
         run_loop.Quit();
       }));
-  base::Value args(base::Value::Type::LIST);
-  web_ui()->HandleReceivedMessage("dialogClose",
-                                  &base::Value::AsListValue(args));
+  base::Value::List args;
+  web_ui()->HandleReceivedMessage("dialogClose", args);
   run_loop.Run();
 }
 
@@ -153,10 +152,9 @@
         json_retval = cb_json_retval;
         run_loop.Quit();
       }));
-  base::Value args(base::Value::Type::LIST);
+  base::Value::List args;
   args.Append(kJsonRetval);
-  web_ui()->HandleReceivedMessage("dialogClose",
-                                  &base::Value::AsListValue(args));
+  web_ui()->HandleReceivedMessage("dialogClose", args);
   run_loop.Run();
   ASSERT_EQ(json_retval, kJsonRetval);
 }
diff --git a/chrome/browser/ui/webui/settings/about_handler_unittest.cc b/chrome/browser/ui/webui/settings/about_handler_unittest.cc
index 4c9ad91..33a51e9ce 100644
--- a/chrome/browser/ui/webui/settings/about_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/about_handler_unittest.cc
@@ -66,10 +66,9 @@
   std::string CallGetEndOfLifeInfoAndReturnString(bool has_eol_passed) {
     size_t call_data_count_before_call = web_ui_.call_data().size();
 
-    base::Value args(base::Value::Type::LIST);
+    base::Value::List args;
     args.Append("handlerFunctionName");
-    web_ui_.HandleReceivedMessage("getEndOfLifeInfo",
-                                  &base::Value::AsListValue(args));
+    web_ui_.HandleReceivedMessage("getEndOfLifeInfo", args);
     task_environment_.RunUntilIdle();
 
     EXPECT_EQ(call_data_count_before_call + 1u, web_ui_.call_data().size());
diff --git a/chrome/browser/ui/webui/settings/chromeos/account_manager_handler_browsertest.cc b/chrome/browser/ui/webui/settings/chromeos/account_manager_handler_browsertest.cc
index 6620ce0a..493211b 100644
--- a/chrome/browser/ui/webui/settings/chromeos/account_manager_handler_browsertest.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/account_manager_handler_browsertest.cc
@@ -293,10 +293,9 @@
   ASSERT_EQ(1UL, account_manager_accounts.size());
 
   // Call "getAccounts".
-  base::Value args(base::Value::Type::LIST);
+  base::Value::List args;
   args.Append(kHandleFunctionName);
-  web_ui()->HandleReceivedMessage(kGetAccountsMessage,
-                                  &base::Value::AsListValue(args));
+  web_ui()->HandleReceivedMessage(kGetAccountsMessage, args);
 
   const content::TestWebUI::CallData& call_data = *web_ui()->call_data().back();
   EXPECT_EQ("cr.webUIResponse", call_data.function_name());
@@ -343,10 +342,9 @@
   base::RunLoop().RunUntilIdle();
 
   // Call "getAccounts".
-  base::Value args(base::Value::Type::LIST);
+  base::Value::List args;
   args.Append(kHandleFunctionName);
-  web_ui()->HandleReceivedMessage(kGetAccountsMessage,
-                                  &base::Value::AsListValue(args));
+  web_ui()->HandleReceivedMessage(kGetAccountsMessage, args);
 
   const content::TestWebUI::CallData& call_data = *web_ui()->call_data().back();
   EXPECT_EQ("cr.webUIResponse", call_data.function_name());
@@ -524,10 +522,9 @@
                                                           false);
 
   // Call "getAccounts".
-  base::Value args(base::Value::Type::LIST);
+  base::Value::List args;
   args.Append(kHandleFunctionName);
-  web_ui()->HandleReceivedMessage(kGetAccountsMessage,
-                                  &base::Value::AsListValue(args));
+  web_ui()->HandleReceivedMessage(kGetAccountsMessage, args);
 
   // Wait for the async calls to finish.
   base::RunLoop().RunUntilIdle();
@@ -600,10 +597,9 @@
   }
 
   // Call "getAccounts".
-  base::Value args(base::Value::Type::LIST);
+  base::Value::List args;
   args.Append(kHandleFunctionName);
-  web_ui()->HandleReceivedMessage(kGetAccountsMessage,
-                                  &base::Value::AsListValue(args));
+  web_ui()->HandleReceivedMessage(kGetAccountsMessage, args);
 
   // Wait for the async calls to finish.
   base::RunLoop().RunUntilIdle();
@@ -617,11 +613,10 @@
   ASSERT_TRUE(secondary_1_dict.has_value());
 
   // Call "changeArcAvailability".
-  base::Value args_1(base::Value::Type::LIST);
+  base::Value::List args_1;
   args_1.Append(secondary_1_dict.value().Clone());  // account
   args_1.Append(false);                             // is_available
-  web_ui()->HandleReceivedMessage("changeArcAvailability",
-                                  &base::Value::AsListValue(args_1));
+  web_ui()->HandleReceivedMessage("changeArcAvailability", args_1);
 
   // Wait for the async calls to finish.
   base::RunLoop().RunUntilIdle();
diff --git a/chrome/browser/ui/webui/settings/chromeos/bluetooth_handler_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/bluetooth_handler_unittest.cc
index b92a01f..9c91d2f8 100644
--- a/chrome/browser/ui/webui/settings/chromeos/bluetooth_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/bluetooth_handler_unittest.cc
@@ -75,11 +75,10 @@
 
   size_t call_data_count_before_call = test_web_ui()->call_data().size();
 
-  base::Value args(base::Value::Type::LIST);
+  base::Value::List args;
   args.Append("handlerFunctionName");
   args.Append(kDeviceAddress);
-  test_web_ui()->HandleReceivedMessage("isDeviceBlockedByPolicy",
-                                       &base::Value::AsListValue(args));
+  test_web_ui()->HandleReceivedMessage("isDeviceBlockedByPolicy", args);
 
   ASSERT_EQ(call_data_count_before_call + 1u,
             test_web_ui()->call_data().size());
@@ -96,9 +95,9 @@
 
   size_t call_data_count_before_call = test_web_ui()->call_data().size();
 
-  base::Value args(base::Value::Type::LIST);
+  base::Value::List args;
   test_web_ui()->HandleReceivedMessage("requestFastPairDeviceSupportStatus",
-                                       &base::Value::AsListValue(args));
+                                       args);
 
   ASSERT_EQ(call_data_count_before_call + 1u,
             test_web_ui()->call_data().size());
diff --git a/chrome/browser/ui/webui/settings/chromeos/change_picture_handler_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/change_picture_handler_unittest.cc
index 624c1a4..bc0832c 100644
--- a/chrome/browser/ui/webui/settings/chromeos/change_picture_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/change_picture_handler_unittest.cc
@@ -108,20 +108,20 @@
   }
 
   void SelectNewDefaultImage(int default_image_index) {
-    base::ListValue args;
+    base::Value::List args;
     args.Append(
         default_user_image::GetDefaultImageUrl(default_image_index).spec());
     args.Append("default");
 
-    web_ui_->HandleReceivedMessage("selectImage", &args);
+    web_ui_->HandleReceivedMessage("selectImage", args);
   }
 
   void SelectProfileImage() {
-    base::ListValue args;
+    base::Value::List args;
     args.Append("empty url");
     args.Append("profile");
 
-    web_ui_->HandleReceivedMessage("selectImage", &args);
+    web_ui_->HandleReceivedMessage("selectImage", args);
   }
 
   void SelectImageFromFile(const base::FilePath& path) {
diff --git a/chrome/browser/ui/webui/settings/chromeos/fast_pair_saved_devices_handler_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/fast_pair_saved_devices_handler_unittest.cc
index 27740ac..439ad8e0 100644
--- a/chrome/browser/ui/webui/settings/chromeos/fast_pair_saved_devices_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/fast_pair_saved_devices_handler_unittest.cc
@@ -260,17 +260,15 @@
 
   void LoadPage() {
     // `HandleReceivedMessages` has to use a ListValue due to the API.
-    base::Value args(base::Value::Type::LIST);
-    test_web_ui()->HandleReceivedMessage(kLoadSavedDevicePage,
-                                         &base::Value::AsListValue(args));
+    base::Value::List args;
+    test_web_ui()->HandleReceivedMessage(kLoadSavedDevicePage, args);
   }
 
   void RemoveDevice(const std::vector<uint8_t>& account_key) {
     // `HandleReceivedMessages` has to use a ListValue due to the API.
-    base::Value args(base::Value::Type::LIST);
+    base::Value::List args;
     args.Append(EncodeKey(account_key));
-    test_web_ui()->HandleReceivedMessage(kRemoveSavedDevice,
-                                         &base::Value::AsListValue(args));
+    test_web_ui()->HandleReceivedMessage(kRemoveSavedDevice, args);
   }
 
   base::HistogramTester& histogram_tester() { return histogram_tester_; }
diff --git a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler_unittest.cc
index ebc51dfb..05b0e6b 100644
--- a/chrome/browser/ui/webui/settings/chromeos/multidevice_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/multidevice_handler_unittest.cc
@@ -342,10 +342,9 @@
   void CallGetPageContentData() {
     size_t call_data_count_before_call = test_web_ui()->call_data().size();
 
-    base::Value args(base::Value::Type::LIST);
+    base::Value::List args;
     args.Append("handlerFunctionName");
-    test_web_ui()->HandleReceivedMessage("getPageContentData",
-                                         &base::Value::AsListValue(args));
+    test_web_ui()->HandleReceivedMessage("getPageContentData", args);
 
     EXPECT_EQ(call_data_count_before_call + 1u,
               test_web_ui()->call_data().size());
@@ -361,8 +360,8 @@
   void CallRemoveHostDevice() {
     size_t num_remote_host_device_calls_before_call =
         fake_multidevice_setup_client()->num_remove_host_device_called();
-    base::ListValue empty_args;
-    test_web_ui()->HandleReceivedMessage("removeHostDevice", &empty_args);
+    base::Value::List empty_args;
+    test_web_ui()->HandleReceivedMessage("removeHostDevice", empty_args);
     EXPECT_EQ(num_remote_host_device_calls_before_call + 1u,
               fake_multidevice_setup_client()->num_remove_host_device_called());
   }
@@ -370,10 +369,9 @@
   void CallGetAndroidSmsInfo(bool expected_enabled, const GURL& expected_url) {
     size_t call_data_count_before_call = test_web_ui()->call_data().size();
 
-    base::ListValue args;
+    base::Value::List args;
     args.Append("handlerFunctionName");
-    test_web_ui()->HandleReceivedMessage("getAndroidSmsInfo",
-                                         &base::Value::AsListValue(args));
+    test_web_ui()->HandleReceivedMessage("getAndroidSmsInfo", args);
 
     ASSERT_EQ(call_data_count_before_call + 1u,
               test_web_ui()->call_data().size());
@@ -399,15 +397,14 @@
                       kAvailableButNotGranted,
             phonehub::MultideviceFeatureAccessManager::AccessProhibitedReason::
                 kUnknown);
-    base::ListValue empty_args;
+    base::Value::List empty_args;
     test_web_ui()->HandleReceivedMessage("attemptNotificationSetup",
-                                         &empty_args);
+                                         empty_args);
   }
 
   void CallCancelNotificationSetup() {
-    base::ListValue empty_args;
-    test_web_ui()->HandleReceivedMessage("cancelNotificationSetup",
-                                         &empty_args);
+    base::Value::List empty_args;
+    test_web_ui()->HandleReceivedMessage("cancelNotificationSetup", empty_args);
   }
 
   void CallAttemptAppsSetup(bool has_access_been_granted) {
@@ -416,13 +413,13 @@
                                       AccessStatus::kAccessGranted
                                 : phonehub::MultideviceFeatureAccessManager::
                                       AccessStatus::kAvailableButNotGranted);
-    base::ListValue empty_args;
-    test_web_ui()->HandleReceivedMessage("attemptAppsSetup", &empty_args);
+    base::Value::List empty_args;
+    test_web_ui()->HandleReceivedMessage("attemptAppsSetup", empty_args);
   }
 
   void CallCancelAppsSetup() {
-    base::ListValue empty_args;
-    test_web_ui()->HandleReceivedMessage("cancelAppsSetup", &empty_args);
+    base::Value::List empty_args;
+    test_web_ui()->HandleReceivedMessage("cancelAppsSetup", empty_args);
   }
 
   void CallAttemptCameraRollSetup(bool has_camera_roll_access_been_granted) {
@@ -433,16 +430,16 @@
                       kAccessGranted
                 : phonehub::MultideviceFeatureAccessManager::AccessStatus::
                       kAvailableButNotGranted);
-    base::ListValue args;
+    base::Value::List args;
     args.Append(/*camera_roll=*/true);
     args.Append(/*notifications=*/false);
-    test_web_ui()->HandleReceivedMessage("attemptCombinedFeatureSetup", &args);
+    test_web_ui()->HandleReceivedMessage("attemptCombinedFeatureSetup", args);
   }
 
   void CallCancelCameraRollSetup() {
-    base::ListValue empty_args;
+    base::Value::List empty_args;
     test_web_ui()->HandleReceivedMessage("cancelCombinedFeatureSetup",
-                                         &empty_args);
+                                         empty_args);
   }
 
   void SimulateHostStatusUpdate(
@@ -607,15 +604,15 @@
   }
 
   void CallRetryPendingHostSetup(bool success) {
-    base::ListValue empty_args;
-    test_web_ui()->HandleReceivedMessage("retryPendingHostSetup", &empty_args);
+    base::Value::List empty_args;
+    test_web_ui()->HandleReceivedMessage("retryPendingHostSetup", empty_args);
     fake_multidevice_setup_client()->InvokePendingRetrySetHostNowCallback(
         success);
   }
 
   void CallSetUpAndroidSms() {
-    base::ListValue empty_args;
-    test_web_ui()->HandleReceivedMessage("setUpAndroidSms", &empty_args);
+    base::Value::List empty_args;
+    test_web_ui()->HandleReceivedMessage("setUpAndroidSms", empty_args);
   }
 
   void CallSetFeatureEnabledState(multidevice_setup::mojom::Feature feature,
@@ -624,16 +621,15 @@
                                   bool success) {
     size_t call_data_count_before_call = test_web_ui()->call_data().size();
 
-    base::Value args(base::Value::Type::LIST);
+    base::Value::List args;
     args.Append("handlerFunctionName");
     args.Append(static_cast<int>(feature));
     args.Append(enabled);
     if (auth_token)
       args.Append(*auth_token);
 
-    base::ListValue empty_args;
-    test_web_ui()->HandleReceivedMessage("setFeatureEnabledState",
-                                         &base::Value::AsListValue(args));
+    base::Value::List empty_args;
+    test_web_ui()->HandleReceivedMessage("setFeatureEnabledState", args);
     fake_multidevice_setup_client()
         ->InvokePendingSetFeatureEnabledStateCallback(
             feature /* expected_feature */, enabled /* expected_enabled */,
@@ -842,10 +838,9 @@
 TEST_F(MultideviceHandlerTest, PageContentDataRequestedWithNullManagers) {
   SetUpHandlerWithEmptyManagers();
 
-  base::Value args(base::Value::Type::LIST);
+  base::Value::List args;
   args.Append("handlerFunctionName");
-  test_web_ui()->HandleReceivedMessage("getPageContentData",
-                                       &base::Value::AsListValue(args));
+  test_web_ui()->HandleReceivedMessage("getPageContentData", args);
 }
 
 TEST_F(MultideviceHandlerTest, NotificationSetupFlow) {
@@ -1007,113 +1002,113 @@
   base::HistogramTester histogram_tester;
   histogram_tester.ExpectTotalCount(kDialogIntroActionHistogram, 0);
 
-  base::ListValue set_up_screen_args;
+  base::Value::List set_up_screen_args;
   set_up_screen_args.Append(/*irrelivant_set_up_dialog=*/0);
   set_up_screen_args.Append(/*action_cancel=*/3);
   test_web_ui()->HandleReceivedMessage("logPhoneHubPermissionSetUpScreenAction",
-                                       &set_up_screen_args);
+                                       set_up_screen_args);
   histogram_tester.ExpectTotalCount(kDialogIntroActionHistogram, 0);
 
-  set_up_screen_args.ClearList();
+  set_up_screen_args.clear();
   set_up_screen_args.Append(/*intro_screen_index=*/1);
   set_up_screen_args.Append(/*learn_more=*/2);
   test_web_ui()->HandleReceivedMessage("logPhoneHubPermissionSetUpScreenAction",
-                                       &set_up_screen_args);
+                                       set_up_screen_args);
   histogram_tester.ExpectBucketCount(kDialogIntroActionHistogram,
                                      /*learn_more=*/2, 1);
 
-  set_up_screen_args.ClearList();
+  set_up_screen_args.clear();
   set_up_screen_args.Append(/*intro_screen_index=*/1);
   set_up_screen_args.Append(/*cancel=*/3);
   test_web_ui()->HandleReceivedMessage("logPhoneHubPermissionSetUpScreenAction",
-                                       &set_up_screen_args);
+                                       set_up_screen_args);
   histogram_tester.ExpectBucketCount(kDialogIntroActionHistogram,
                                      /*cancel=*/3, 1);
 
-  set_up_screen_args.ClearList();
+  set_up_screen_args.clear();
   set_up_screen_args.Append(/*intro_screen_index=*/1);
   set_up_screen_args.Append(/*next=*/5);
   test_web_ui()->HandleReceivedMessage("logPhoneHubPermissionSetUpScreenAction",
-                                       &set_up_screen_args);
+                                       set_up_screen_args);
   histogram_tester.ExpectBucketCount(kDialogIntroActionHistogram,
                                      /*done=*/5, 1);
 
-  set_up_screen_args.ClearList();
+  set_up_screen_args.clear();
   set_up_screen_args.Append(/*finish_on_phone_screen_index=*/2);
   set_up_screen_args.Append(/*learn_more=*/2);
   test_web_ui()->HandleReceivedMessage("logPhoneHubPermissionSetUpScreenAction",
-                                       &set_up_screen_args);
+                                       set_up_screen_args);
   histogram_tester.ExpectBucketCount(kDialogFinishOnPhoneActionHistogram,
                                      /*learn_more=*/2, 1);
 
-  set_up_screen_args.ClearList();
+  set_up_screen_args.clear();
   set_up_screen_args.Append(/*finish_on_phone_screen_index=*/2);
   set_up_screen_args.Append(/*cancel=*/3);
   test_web_ui()->HandleReceivedMessage("logPhoneHubPermissionSetUpScreenAction",
-                                       &set_up_screen_args);
+                                       set_up_screen_args);
   histogram_tester.ExpectBucketCount(kDialogFinishOnPhoneActionHistogram,
                                      /*cancel=*/3, 1);
 
-  set_up_screen_args.ClearList();
+  set_up_screen_args.clear();
   set_up_screen_args.Append(/*connecting_screen_index=*/3);
   set_up_screen_args.Append(/*cancel=*/3);
   test_web_ui()->HandleReceivedMessage("logPhoneHubPermissionSetUpScreenAction",
-                                       &set_up_screen_args);
+                                       set_up_screen_args);
   histogram_tester.ExpectBucketCount(kDialogConnectingActionHistogram,
                                      /*cancel=*/3, 1);
 
-  set_up_screen_args.ClearList();
+  set_up_screen_args.clear();
   set_up_screen_args.Append(/*connected_screen_index=*/6);
   set_up_screen_args.Append(/*done=*/4);
   test_web_ui()->HandleReceivedMessage("logPhoneHubPermissionSetUpScreenAction",
-                                       &set_up_screen_args);
+                                       set_up_screen_args);
   histogram_tester.ExpectBucketCount(kDialogSetupFinishedActionHistogram,
                                      /*done=*/4, 1);
 
-  set_up_screen_args.ClearList();
+  set_up_screen_args.clear();
   set_up_screen_args.Append(/*connection_error_screen_index=*/4);
   set_up_screen_args.Append(/*try_again=*/5);
   test_web_ui()->HandleReceivedMessage("logPhoneHubPermissionSetUpScreenAction",
-                                       &set_up_screen_args);
+                                       set_up_screen_args);
   histogram_tester.ExpectBucketCount(kDialogConnectionErrorActionHistogram,
                                      /*try_again=*/5, 1);
 
-  set_up_screen_args.ClearList();
+  set_up_screen_args.clear();
   set_up_screen_args.Append(/*connection_error_screen_index=*/4);
   set_up_screen_args.Append(/*cancel=*/3);
   test_web_ui()->HandleReceivedMessage("logPhoneHubPermissionSetUpScreenAction",
-                                       &set_up_screen_args);
+                                       set_up_screen_args);
   histogram_tester.ExpectBucketCount(kDialogConnectionErrorActionHistogram,
                                      /*cancel=*/3, 1);
 
-  set_up_screen_args.ClearList();
+  set_up_screen_args.clear();
   set_up_screen_args.Append(/*connection_time_out_screen_index=*/5);
   set_up_screen_args.Append(/*try_again=*/5);
   test_web_ui()->HandleReceivedMessage("logPhoneHubPermissionSetUpScreenAction",
-                                       &set_up_screen_args);
+                                       set_up_screen_args);
   histogram_tester.ExpectBucketCount(kDialogConnectionTimeOutActionHistogram,
                                      /*try_again=*/5, 1);
 
-  set_up_screen_args.ClearList();
+  set_up_screen_args.clear();
   set_up_screen_args.Append(/*connection_time_out_screen_index=*/5);
   set_up_screen_args.Append(/*cancel=*/3);
   test_web_ui()->HandleReceivedMessage("logPhoneHubPermissionSetUpScreenAction",
-                                       &set_up_screen_args);
+                                       set_up_screen_args);
   histogram_tester.ExpectBucketCount(kDialogConnectionTimeOutActionHistogram,
                                      /*cancel=*/3, 1);
 
-  set_up_screen_args.ClearList();
+  set_up_screen_args.clear();
   set_up_screen_args.Append(/*set_a_pin_screen_index=*/7);
   set_up_screen_args.Append(/*cancel=*/3);
   test_web_ui()->HandleReceivedMessage("logPhoneHubPermissionSetUpScreenAction",
-                                       &set_up_screen_args);
+                                       set_up_screen_args);
   histogram_tester.ExpectBucketCount(kDialogSetAPinOrPasswordHistogram,
                                      /*cancel=*/3, 1);
 
-  set_up_screen_args.ClearList();
+  set_up_screen_args.clear();
   set_up_screen_args.Append(/*camera_roll_setup=*/3);
   test_web_ui()->HandleReceivedMessage(
-      "logPhoneHubPermissionSetUpButtonClicked", &set_up_screen_args);
+      "logPhoneHubPermissionSetUpButtonClicked", set_up_screen_args);
   histogram_tester.ExpectBucketCount(kSetupButtonInSettingsClikedHistogram,
                                      /*camera_roll_setup=*/3, 1);
 }
diff --git a/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc b/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
index 2331486..c045b3cc 100644
--- a/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.cc
@@ -153,17 +153,17 @@
   // types that the user cleared from the clear browsing data UI and time period
   // of the data to be cleared.
 
-  base::Value data_types(base::Value::Type::LIST);
+  base::Value::List data_types;
   data_types.Append("browser.clear_data.browsing_history");
 
-  base::Value installed_apps(base::Value::Type::LIST);
+  base::Value::List installed_apps;
 
-  base::Value list_args(base::Value::Type::LIST);
+  base::Value::List list_args;
   list_args.Append("webui_callback_id");
   list_args.Append(std::move(data_types));
   list_args.Append(1);
   list_args.Append(std::move(installed_apps));
-  HandleClearBrowsingData(list_args.GetList());
+  HandleClearBrowsingData(list_args);
 }
 
 void ClearBrowsingDataHandler::GetRecentlyLaunchedInstalledApps(
@@ -203,29 +203,28 @@
     installed_apps_list.Append(std::move(entry));
   }
   ResolveJavascriptCallback(base::Value(webui_callback_id),
-                            base::Value(std::move(installed_apps_list)));
+                            installed_apps_list);
 }
 
 std::unique_ptr<content::BrowsingDataFilterBuilder>
 ClearBrowsingDataHandler::ProcessInstalledApps(
-    base::Value::ConstListView installed_apps) {
+    const base::Value::List& installed_apps) {
   std::vector<std::string> excluded_domains;
   std::vector<int32_t> excluded_domain_reasons;
   std::vector<std::string> ignored_domains;
   std::vector<int32_t> ignored_domain_reasons;
   for (const auto& item : installed_apps) {
-    const base::DictionaryValue* site = nullptr;
-    CHECK(item.GetAsDictionary(&site));
-    bool is_checked = site->FindBoolPath(kIsCheckedField).value();
-    std::string domain;
-    CHECK(site->GetString(kRegisterableDomainField, &domain));
-    absl::optional<int> domain_reason = site->FindIntKey(kReasonBitfieldField);
+    const base::Value::Dict& site = item.GetDict();
+    bool is_checked = site.FindBool(kIsCheckedField).value();
+    const std::string* domain = site.FindString(kRegisterableDomainField);
+    CHECK(domain);
+    absl::optional<int> domain_reason = site.FindInt(kReasonBitfieldField);
     CHECK(domain_reason);
     if (is_checked) {  // Selected installed apps should be deleted.
-      ignored_domains.push_back(domain);
+      ignored_domains.push_back(*domain);
       ignored_domain_reasons.push_back(*domain_reason);
     } else {  // Unselected sites should be kept.
-      excluded_domains.push_back(domain);
+      excluded_domains.push_back(*domain);
       excluded_domain_reasons.push_back(*domain_reason);
     }
   }
@@ -259,7 +258,7 @@
   std::vector<BrowsingDataType> data_type_vector;
 
   CHECK(args_list[1].is_list());
-  base::Value::ConstListView data_type_list = args_list[1].GetListDeprecated();
+  const base::Value::List& data_type_list = args_list[1].GetList();
   for (const base::Value& type : data_type_list) {
     const std::string pref_name = type.GetString();
     BrowsingDataType data_type =
@@ -358,8 +357,7 @@
 
   int period_selected = args_list[2].GetInt();
 
-  const base::Value::ConstListView installed_apps =
-      args_list[3].GetListDeprecated();
+  const base::Value::List& installed_apps = args_list[3].GetList();
   std::unique_ptr<content::BrowsingDataFilterBuilder> filter_builder =
       ProcessInstalledApps(installed_apps);
 
@@ -410,11 +408,11 @@
   bool show_passwords_notice =
       (failed_data_types & chrome_browsing_data_remover::DATA_TYPE_PASSWORDS);
 
-  base::Value result(base::Value::Type::DICTIONARY);
-  result.SetBoolKey("showHistoryNotice", show_history_notice);
-  result.SetBoolKey("showPasswordsNotice", show_passwords_notice);
+  base::Value::Dict result;
+  result.Set("showHistoryNotice", show_history_notice);
+  result.Set("showPasswordsNotice", show_passwords_notice);
 
-  ResolveJavascriptCallback(base::Value(webui_callback_id), std::move(result));
+  ResolveJavascriptCallback(base::Value(webui_callback_id), result);
 }
 
 void ClearBrowsingDataHandler::HandleInitialize(const base::Value::List& args) {
@@ -449,33 +447,31 @@
   FireWebUIListener("update-sync-state", CreateSyncStateEvent());
 }
 
-base::DictionaryValue ClearBrowsingDataHandler::CreateSyncStateEvent() {
+base::Value::Dict ClearBrowsingDataHandler::CreateSyncStateEvent() {
   signin::IdentityManager* identity_manager =
       IdentityManagerFactory::GetForProfile(profile_);
-  base::DictionaryValue event;
-  event.SetBoolKey("signedIn",
-                   identity_manager && identity_manager->HasPrimaryAccount(
-                                           signin::ConsentLevel::kSignin));
-  event.SetBoolKey("syncConsented",
-                   identity_manager && identity_manager->HasPrimaryAccount(
-                                           signin::ConsentLevel::kSync));
-  event.SetBoolKey("syncingHistory",
-                   sync_service_ && sync_service_->IsSyncFeatureActive() &&
-                       sync_service_->GetActiveDataTypes().Has(
-                           syncer::HISTORY_DELETE_DIRECTIVES));
-  event.SetBoolKey(
-      "shouldShowCookieException",
-      browsing_data_counter_utils::ShouldShowCookieException(profile_));
+  base::Value::Dict event;
+  event.Set("signedIn", identity_manager && identity_manager->HasPrimaryAccount(
+                                                signin::ConsentLevel::kSignin));
+  event.Set("syncConsented",
+            identity_manager && identity_manager->HasPrimaryAccount(
+                                    signin::ConsentLevel::kSync));
+  event.Set("syncingHistory", sync_service_ &&
+                                  sync_service_->IsSyncFeatureActive() &&
+                                  sync_service_->GetActiveDataTypes().Has(
+                                      syncer::HISTORY_DELETE_DIRECTIVES));
+  event.Set("shouldShowCookieException",
+            browsing_data_counter_utils::ShouldShowCookieException(profile_));
 
-  event.SetBoolKey("isNonGoogleDse", false);
+  event.Set("isNonGoogleDse", false);
   const TemplateURLService* template_url_service =
       TemplateURLServiceFactory::GetForProfile(profile_);
   const TemplateURL* dse = template_url_service->GetDefaultSearchProvider();
   if (dse && dse->GetEngineType(template_url_service->search_terms_data()) !=
                  SearchEngineType::SEARCH_ENGINE_GOOGLE) {
     // Non-Google DSE. Prepopulated DSEs have an ID > 0.
-    event.SetBoolKey("isNonGoogleDse", true);
-    event.SetStringKey(
+    event.Set("isNonGoogleDse", true);
+    event.Set(
         "nonGoogleSearchHistoryString",
         (dse->prepopulate_id() > 0)
             ? l10n_util::GetStringFUTF16(
diff --git a/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h b/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h
index 798bb9a..e3a867e 100644
--- a/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h
+++ b/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler.h
@@ -77,7 +77,7 @@
   // based on whether installed apps were marked for deletion by the checkbox on
   // the installed apps warning dialog.
   std::unique_ptr<content::BrowsingDataFilterBuilder> ProcessInstalledApps(
-      base::Value::ConstListView installed_apps);
+      const base::Value::List& installed_apps);
 
   // Clears browsing data, called by Javascript.
   void HandleClearBrowsingData(const base::Value::List& value);
@@ -105,7 +105,7 @@
   virtual void UpdateSyncState();
 
   // Create a SyncStateEvent containing the current sync state.
-  base::DictionaryValue CreateSyncStateEvent();
+  base::Value::Dict CreateSyncStateEvent();
 
   // Finds out whether we should show notice about other forms of history stored
   // in user's account.
diff --git a/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler_browsertest.cc b/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler_browsertest.cc
index f3b22d4..ae9284c5 100644
--- a/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler_browsertest.cc
+++ b/chrome/browser/ui/webui/settings/settings_clear_browsing_data_handler_browsertest.cc
@@ -82,12 +82,11 @@
 IN_PROC_BROWSER_TEST_F(ClearBrowsingDataHandlerBrowserTest, GetInstalledApps) {
   GURL url(https_server()->GetURL("/title1.html"));
   InstallAndLaunchApp(url);
-  base::Value args(base::Value::Type::LIST);
+  base::Value::List args;
   args.Append(kWebUiFunctionName);
   args.Append(1);
 
-  web_ui()->HandleReceivedMessage(kGetInstalledApps,
-                                  &base::Value::AsListValue(args));
+  web_ui()->HandleReceivedMessage(kGetInstalledApps, args);
   const content::TestWebUI::CallData& call_data = *web_ui()->call_data().back();
   EXPECT_EQ("cr.webUIResponse", call_data.function_name());
   EXPECT_EQ(kWebUiFunctionName, call_data.arg1()->GetString());
diff --git a/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc b/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc
index 38e2710e..531308b 100644
--- a/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_cookies_view_handler.cc
@@ -255,8 +255,7 @@
 
   base::Value::List children = model_util_->GetChildNodeDetailsDeprecated(node);
 
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(children)));
+  ResolveJavascriptCallback(base::Value(callback_id), children);
 }
 
 void CookiesViewHandler::HandleGetNumCookiesString(
@@ -473,8 +472,7 @@
               return *a.FindStringKey(kSite) < *b.FindStringKey(kSite);
             });
 
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(site_list)));
+  ResolveJavascriptCallback(base::Value(callback_id), site_list);
 }
 
 void CookiesViewHandler::ProcessPendingRequests() {
diff --git a/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc b/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc
index 90a9107..3e31994 100644
--- a/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_default_browser_handler.cc
@@ -98,12 +98,11 @@
     ResetDefaultBrowserPrompt(Profile::FromWebUI(web_ui()));
   }
 
-  base::DictionaryValue dict;
-  dict.SetBoolKey("isDefault", state == shell_integration::IS_DEFAULT);
-  dict.SetBoolKey("canBeDefault", shell_integration::CanSetAsDefaultBrowser());
-  dict.SetBoolKey("isUnknownError",
-                  state == shell_integration::UNKNOWN_DEFAULT);
-  dict.SetBoolKey("isDisabledByPolicy", DefaultBrowserIsDisabledByPolicy());
+  base::Value::Dict dict;
+  dict.Set("isDefault", state == shell_integration::IS_DEFAULT);
+  dict.Set("canBeDefault", shell_integration::CanSetAsDefaultBrowser());
+  dict.Set("isUnknownError", state == shell_integration::UNKNOWN_DEFAULT);
+  dict.Set("isDisabledByPolicy", DefaultBrowserIsDisabledByPolicy());
 
   if (!check_default_callback_id_.empty()) {
     ResolveJavascriptCallback(base::Value(check_default_callback_id_), dict);
diff --git a/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc b/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
index 5591f218..8237994 100644
--- a/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_manage_profile_handler.cc
@@ -103,8 +103,7 @@
     return;
 
   // GAIA image is loaded asynchronously.
-  FireWebUIListener("available-icons-changed",
-                    base::Value(GetAvailableIcons()));
+  FireWebUIListener("available-icons-changed", GetAvailableIcons());
 }
 
 void ManageProfileHandler::OnProfileAvatarChanged(
@@ -113,8 +112,7 @@
     return;
 
   // This is necessary to send the potentially updated GAIA photo.
-  FireWebUIListener("available-icons-changed",
-                    base::Value(GetAvailableIcons()));
+  FireWebUIListener("available-icons-changed", GetAvailableIcons());
 }
 
 void ManageProfileHandler::OnProfileThemeColorsChanged(
@@ -132,7 +130,7 @@
   CHECK_EQ(1U, args.size());
   const base::Value& callback_id = args[0];
 
-  ResolveJavascriptCallback(callback_id, base::Value(GetAvailableIcons()));
+  ResolveJavascriptCallback(callback_id, GetAvailableIcons());
 }
 
 base::Value::List ManageProfileHandler::GetAvailableIcons() {
diff --git a/chrome/browser/ui/webui/settings/settings_media_devices_selection_handler.cc b/chrome/browser/ui/webui/settings/settings_media_devices_selection_handler.cc
index 3c4be909..2c64665 100644
--- a/chrome/browser/ui/webui/settings/settings_media_devices_selection_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_media_devices_selection_handler.cc
@@ -143,9 +143,8 @@
 
   base::Value default_value(default_id);
   base::Value type_value(device_type);
-  base::Value device_list_value(std::move(device_list));
 
-  FireWebUIListener("updateDevicesMenu", type_value, device_list_value,
+  FireWebUIListener("updateDevicesMenu", type_value, device_list,
                     default_value);
 }
 
diff --git a/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc b/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc
index 3d33abf..ac1d41af 100644
--- a/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_secure_dns_handler.cc
@@ -35,7 +35,7 @@
 
 namespace {
 
-base::Value CreateSecureDnsSettingDict() {
+base::Value::Dict CreateSecureDnsSettingDict() {
   // Fetch the current host resolver configuration. It is not sufficient to read
   // the secure DNS prefs directly since the host resolver configuration takes
   // other factors into account such as whether a managed environment or
@@ -49,7 +49,7 @@
   dict.Set("mode", SecureDnsConfig::ModeToString(config.mode()));
   dict.Set("config", config.doh_servers().ToString());
   dict.Set("managementMode", static_cast<int>(config.management_mode()));
-  return base::Value(std::move(dict));
+  return dict;
 }
 
 }  // namespace
@@ -105,8 +105,16 @@
   pref_registrar_.RemoveAll();
 }
 
-base::Value SecureDnsHandler::GetSecureDnsResolverList() {
+base::Value::List SecureDnsHandler::GetSecureDnsResolverList() {
   base::Value::List resolvers;
+
+  // Add a custom option to the front of the list
+  base::Value::Dict custom;
+  custom.Set("name", l10n_util::GetStringUTF8(IDS_SETTINGS_CUSTOM));
+  custom.Set("value", std::string());  // Empty value means custom.
+  custom.Set("policy", std::string());
+  resolvers.Append(std::move(custom));
+
   for (const auto* entry : providers_) {
     net::DnsOverHttpsConfig doh_config({entry->doh_server_config});
     base::Value::Dict dict;
@@ -116,17 +124,10 @@
     resolvers.Append(std::move(dict));
   }
 
-  // Randomize the order of the resolvers.
-  base::RandomShuffle(resolvers.begin(), resolvers.end());
+  // Randomize the order of the resolvers, but keep custom in first place.
+  base::RandomShuffle(std::next(resolvers.begin()), resolvers.end());
 
-  // Add a custom option to the front of the list
-  base::Value::Dict custom;
-  custom.Set("name", l10n_util::GetStringUTF8(IDS_SETTINGS_CUSTOM));
-  custom.Set("value", std::string());  // Empty value means custom.
-  custom.Set("policy", std::string());
-  resolvers.Insert(resolvers.begin(), base::Value(std::move(custom)));
-
-  return base::Value(std::move(resolvers));
+  return resolvers;
 }
 
 void SecureDnsHandler::SetNetworkContextForTesting(
diff --git a/chrome/browser/ui/webui/settings/settings_secure_dns_handler.h b/chrome/browser/ui/webui/settings/settings_secure_dns_handler.h
index b5d22f1..0ef3d973 100644
--- a/chrome/browser/ui/webui/settings/settings_secure_dns_handler.h
+++ b/chrome/browser/ui/webui/settings/settings_secure_dns_handler.h
@@ -39,7 +39,7 @@
   // as a dictionary with the following keys: "name" (the text to display in the
   // UI), "value" (the DoH template for this provider), and "policy" (the URL of
   // the provider's privacy policy).
-  base::Value GetSecureDnsResolverList();
+  base::Value::List GetSecureDnsResolverList();
 
   void SetNetworkContextForTesting(
       network::mojom::NetworkContext* network_context);
diff --git a/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc b/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc
index c7d4cf5..3d14e84 100644
--- a/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc
+++ b/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc
@@ -92,18 +92,16 @@
   return {&global1, &no_display, &ee_fr, &fr, &global2};
 }
 
-bool FindDropdownItem(const base::Value& resolvers,
+bool FindDropdownItem(const base::Value::List& resolvers,
                       const std::string& name,
                       const std::string& value,
                       const std::string& policy) {
-  base::Value dict(base::Value::Type::DICTIONARY);
-  dict.SetKey("name", base::Value(name));
-  dict.SetKey("value", base::Value(value));
-  dict.SetKey("policy", base::Value(policy));
+  base::Value::Dict dict;
+  dict.Set("name", name);
+  dict.Set("value", value);
+  dict.Set("policy", policy);
 
-  return std::find(resolvers.GetListDeprecated().begin(),
-                   resolvers.GetListDeprecated().end(),
-                   dict) != resolvers.GetListDeprecated().end();
+  return std::find(resolvers.begin(), resolvers.end(), dict) != resolvers.end();
 }
 
 }  // namespace
@@ -305,33 +303,28 @@
 
 // This test makes no assumptions about the country or underlying resolver list.
 IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, DropdownList) {
-  base::Value args(base::Value::Type::LIST);
+  base::Value::List args;
   args.Append(kWebUiFunctionName);
 
-  web_ui_.HandleReceivedMessage(kGetSecureDnsResolverList,
-                                &base::Value::AsListValue(args));
+  web_ui_.HandleReceivedMessage(kGetSecureDnsResolverList, args);
   const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back();
   EXPECT_EQ("cr.webUIResponse", call_data.function_name());
   EXPECT_EQ(kWebUiFunctionName, call_data.arg1()->GetString());
   ASSERT_TRUE(call_data.arg2()->GetBool());
 
   // Check results.
-  base::Value::ConstListView resolver_list =
-      call_data.arg3()->GetListDeprecated();
+  const base::Value::List& resolver_list = call_data.arg3()->GetList();
   ASSERT_GE(resolver_list.size(), 1U);
-  EXPECT_TRUE(resolver_list[0].FindKey("value")->GetString().empty());
+  EXPECT_TRUE(resolver_list[0].GetDict().FindString("value")->empty());
 }
 
 IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, DropdownListContents) {
   const auto entries = GetDohProviderListForTesting();
   handler_->SetProvidersForTesting(entries);
-  const base::Value resolver_list = handler_->GetSecureDnsResolverList();
+  const base::Value::List resolver_list = handler_->GetSecureDnsResolverList();
 
-  EXPECT_EQ(entries.size() + 1, resolver_list.GetListDeprecated().size());
-  EXPECT_TRUE(resolver_list.GetListDeprecated()[0]
-                  .FindKey("value")
-                  ->GetString()
-                  .empty());
+  EXPECT_EQ(entries.size() + 1, resolver_list.size());
+  EXPECT_TRUE(resolver_list[0].GetDict().FindString("value")->empty());
   for (const auto* entry : entries) {
     EXPECT_TRUE(FindDropdownItem(resolver_list, entry->ui_name,
                                  entry->doh_server_config.server_template(),
@@ -343,11 +336,10 @@
   handler_->SetProvidersForTesting(GetDohProviderListForTesting());
 
   base::HistogramTester histograms;
-  base::Value args(base::Value::Type::LIST);
+  base::Value::List args;
   args.Append(std::string() /* old_provider */);
   args.Append("https://global1.provider/dns-query{?dns}" /* new_provider */);
-  web_ui_.HandleReceivedMessage(kRecordUserDropdownInteraction,
-                                &base::Value::AsListValue(args));
+  web_ui_.HandleReceivedMessage(kRecordUserDropdownInteraction, args);
 
   const std::string kUmaBase = "Net.DNS.UI.DropdownSelectionEvent";
   histograms.ExpectTotalCount(kUmaBase + ".Ignored", 4u);
@@ -390,13 +382,12 @@
 }
 
 IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, TemplateValid) {
-  base::Value args(base::Value::Type::LIST);
+  base::Value::List args;
   args.Append(kWebUiFunctionName);
   args.Append("https://example.template/dns-query");
 
   base::HistogramTester histograms;
-  web_ui_.HandleReceivedMessage(kIsValidConfig,
-                                &base::Value::AsListValue(args));
+  web_ui_.HandleReceivedMessage(kIsValidConfig, args);
   const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back();
   EXPECT_EQ("cr.webUIResponse", call_data.function_name());
   EXPECT_EQ(kWebUiFunctionName, call_data.arg1()->GetString());
@@ -409,13 +400,12 @@
 }
 
 IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, TemplateInvalid) {
-  base::Value args(base::Value::Type::LIST);
+  base::Value::List args;
   args.Append(kWebUiFunctionName);
   args.Append("invalid_template");
 
   base::HistogramTester histograms;
-  web_ui_.HandleReceivedMessage(kIsValidConfig,
-                                &base::Value::AsListValue(args));
+  web_ui_.HandleReceivedMessage(kIsValidConfig, args);
   const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back();
   EXPECT_EQ("cr.webUIResponse", call_data.function_name());
   EXPECT_EQ(kWebUiFunctionName, call_data.arg1()->GetString());
@@ -429,12 +419,11 @@
 
 IN_PROC_BROWSER_TEST_F(SecureDnsHandlerTest, MultipleTemplates) {
   base::HistogramTester histograms;
-  base::Value args_valid(base::Value::Type::LIST);
+  base::Value::List args_valid;
   args_valid.Append(kWebUiFunctionName);
   args_valid.Append(
       "https://example1.template/dns    https://example2.template/dns-query");
-  web_ui_.HandleReceivedMessage(kIsValidConfig,
-                                &base::Value::AsListValue(args_valid));
+  web_ui_.HandleReceivedMessage(kIsValidConfig, args_valid);
   const content::TestWebUI::CallData& call_data_valid =
       *web_ui_.call_data().back();
   EXPECT_EQ("cr.webUIResponse", call_data_valid.function_name());
@@ -446,11 +435,10 @@
   histograms.ExpectBucketCount("Net.DNS.UI.ValidationAttemptSuccess", false, 0);
   histograms.ExpectBucketCount("Net.DNS.UI.ValidationAttemptSuccess", true, 1);
 
-  base::Value args_invalid(base::Value::Type::LIST);
+  base::Value::List args_invalid;
   args_invalid.Append(kWebUiFunctionName);
   args_invalid.Append("invalid_template https://example.template/dns");
-  web_ui_.HandleReceivedMessage(kIsValidConfig,
-                                &base::Value::AsListValue(args_invalid));
+  web_ui_.HandleReceivedMessage(kIsValidConfig, args_invalid);
   const content::TestWebUI::CallData& call_data_invalid =
       *web_ui_.call_data().back();
   EXPECT_EQ("cr.webUIResponse", call_data_invalid.function_name());
@@ -475,11 +463,10 @@
                           SingleResult>() /* google_config_result_list */);
   handler_->SetNetworkContextForTesting(network_context_.get());
   base::HistogramTester histograms;
-  base::Value args_valid(base::Value::Type::LIST);
+  base::Value::List args_valid;
   args_valid.Append(kWebUiFunctionName);
   args_valid.Append("https://example.template/dns-query https://example2/");
-  web_ui_.HandleReceivedMessage(kProbeConfig,
-                                &base::Value::AsListValue(args_valid));
+  web_ui_.HandleReceivedMessage(kProbeConfig, args_valid);
   base::RunLoop().RunUntilIdle();
 
   const content::TestWebUI::CallData& call_data_valid =
@@ -507,11 +494,10 @@
                           SingleResult>() /* google_config_result_list */);
   handler_->SetNetworkContextForTesting(network_context_.get());
   base::HistogramTester histograms;
-  base::Value args_valid(base::Value::Type::LIST);
+  base::Value::List args_valid;
   args_valid.Append(kWebUiFunctionName);
   args_valid.Append("https://example.template/dns-query");
-  web_ui_.HandleReceivedMessage(kProbeConfig,
-                                &base::Value::AsListValue(args_valid));
+  web_ui_.HandleReceivedMessage(kProbeConfig, args_valid);
   base::RunLoop().RunUntilIdle();
 
   const content::TestWebUI::CallData& call_data_valid =
@@ -540,13 +526,12 @@
           std::vector<chrome_browser_net::FakeHostResolver::
                           SingleResult>() /* google_config_result_list */);
   base::HistogramTester histograms;
-  base::Value args_valid(base::Value::Type::LIST);
+  base::Value::List args_valid;
   args_valid.Append(kWebUiFunctionName);
   args_valid.Append("https://example.template/dns-query");
   // Request a probe that will hang.
   handler_->SetNetworkContextForTesting(network_context_hang.get());
-  web_ui_.HandleReceivedMessage(kProbeConfig,
-                                &base::Value::AsListValue(args_valid));
+  web_ui_.HandleReceivedMessage(kProbeConfig, args_valid);
   size_t responses = web_ui_.call_data().size();
   base::RunLoop().RunUntilIdle();
   // No response yet from the hanging probe.
@@ -554,8 +539,7 @@
 
   // Request a probe that will fail.
   handler_->SetNetworkContextForTesting(network_context_fail.get());
-  web_ui_.HandleReceivedMessage(kProbeConfig,
-                                &base::Value::AsListValue(args_valid));
+  web_ui_.HandleReceivedMessage(kProbeConfig, args_valid);
   // The hanging response should now have arrived.
   EXPECT_EQ(responses + 1, web_ui_.call_data().size());
   const content::TestWebUI::CallData& first_response =
diff --git a/chrome/browser/ui/webui/settings/settings_security_key_handler.cc b/chrome/browser/ui/webui/settings/settings_security_key_handler.cc
index 72c9e1b..8d296e6 100644
--- a/chrome/browser/ui/webui/settings/settings_security_key_handler.cc
+++ b/chrome/browser/ui/webui/settings/settings_security_key_handler.cc
@@ -160,8 +160,7 @@
     response.Set("retries", base::Value());
   }
 
-  ResolveJavascriptCallback(base::Value(std::move(callback_id_)),
-                            base::Value(std::move(response)));
+  ResolveJavascriptCallback(base::Value(std::move(callback_id_)), response);
 }
 
 void SecurityKeysPINHandler::OnSetPINComplete(
@@ -180,8 +179,7 @@
   base::Value::Dict response;
   response.Set("done", true);
   response.Set("error", static_cast<int>(code));
-  ResolveJavascriptCallback(base::Value(std::move(callback_id_)),
-                            base::Value(std::move(response)));
+  ResolveJavascriptCallback(base::Value(std::move(callback_id_)), response);
 }
 
 void SecurityKeysPINHandler::HandleSetPIN(const base::Value::List& args) {
@@ -533,8 +531,7 @@
     }
   }
 
-  ResolveJavascriptCallback(base::Value(std::move(callback_id_)),
-                            base::Value(std::move(credentials)));
+  ResolveJavascriptCallback(base::Value(std::move(callback_id_)), credentials);
 }
 
 void SecurityKeysCredentialHandler::OnGatherPIN(
@@ -554,8 +551,7 @@
     response.Set("supportsUpdateUserInformation",
                  authenticator_properties.supports_update_user_information);
     state_ = State::kPIN;
-    ResolveJavascriptCallback(base::Value(std::move(callback_id_)),
-                              base::Value(std::move(response)));
+    ResolveJavascriptCallback(base::Value(std::move(callback_id_)), response);
     return;
   }
 
@@ -564,8 +560,7 @@
   base::Value::List response;
   response.Append(static_cast<int>(authenticator_properties.min_pin_length));
   response.Append(static_cast<int>(authenticator_properties.pin_retries));
-  ResolveJavascriptCallback(base::Value(std::move(callback_id_)),
-                            base::Value(std::move(response)));
+  ResolveJavascriptCallback(base::Value(std::move(callback_id_)), response);
 }
 
 void SecurityKeysCredentialHandler::OnCredentialsDeleted(
@@ -586,8 +581,7 @@
           status == device::CtapDeviceResponseCode::kSuccess
               ? IDS_SETTINGS_SECURITY_KEYS_CREDENTIAL_MANAGEMENT_DELETE_SUCCESS
               : IDS_SETTINGS_SECURITY_KEYS_CREDENTIAL_MANAGEMENT_DELETE_FAILED));
-  ResolveJavascriptCallback(base::Value(std::move(callback_id_)),
-                            base::Value(std::move(response)));
+  ResolveJavascriptCallback(base::Value(std::move(callback_id_)), response);
 }
 
 void SecurityKeysCredentialHandler::OnUserInformationUpdated(
@@ -608,8 +602,7 @@
           status == device::CtapDeviceResponseCode::kSuccess
               ? IDS_SETTINGS_SECURITY_KEYS_CREDENTIAL_MANAGEMENT_UPDATE_SUCCESS
               : IDS_SETTINGS_SECURITY_KEYS_CREDENTIAL_MANAGEMENT_UPDATE_FAILED));
-  ResolveJavascriptCallback(base::Value(std::move(callback_id_)),
-                            base::Value(std::move(response)));
+  ResolveJavascriptCallback(base::Value(std::move(callback_id_)), response);
 }
 
 void SecurityKeysCredentialHandler::OnFinished(
@@ -802,8 +795,7 @@
   base::Value::List response;
   response.Append(static_cast<int>(min_pin_length));
   response.Append(static_cast<int>(retries));
-  ResolveJavascriptCallback(base::Value(std::move(callback_id_)),
-                            base::Value(std::move(response)));
+  ResolveJavascriptCallback(base::Value(std::move(callback_id_)), response);
 }
 
 void SecurityKeysBioEnrollmentHandler::HandleProvidePIN(
@@ -828,7 +820,7 @@
     response.Set("maxSamplesForEnroll", *sensor_info_.max_samples_for_enroll);
   }
   ResolveJavascriptCallback(base::Value(std::move(args[0].GetString())),
-                            base::Value(std::move(response)));
+                            response);
 }
 
 void SecurityKeysBioEnrollmentHandler::HandleEnumerate(
@@ -858,8 +850,7 @@
   }
 
   state_ = State::kReady;
-  ResolveJavascriptCallback(base::Value(std::move(callback_id_)),
-                            base::Value(std::move(list)));
+  ResolveJavascriptCallback(base::Value(std::move(callback_id_)), list);
 }
 
 void SecurityKeysBioEnrollmentHandler::HandleStartEnrolling(
@@ -884,8 +875,7 @@
   base::Value::Dict d;
   d.Set("status", static_cast<int>(status));
   d.Set("remaining", static_cast<int>(remaining_samples));
-  FireWebUIListener("security-keys-bio-enroll-status",
-                    base::Value(std::move(d)));
+  FireWebUIListener("security-keys-bio-enroll-status", d);
 }
 
 void SecurityKeysBioEnrollmentHandler::OnEnrollmentFinished(
@@ -899,8 +889,7 @@
     base::Value::Dict d;
     d.Set("code", static_cast<int>(code));
     d.Set("remaining", 0);
-    ResolveJavascriptCallback(base::Value(std::move(callback_id_)),
-                              base::Value(std::move(d)));
+    ResolveJavascriptCallback(base::Value(std::move(callback_id_)), d);
     return;
   }
   if (code != device::CtapDeviceResponseCode::kSuccess) {
@@ -930,8 +919,7 @@
   d.Set("remaining", 0);
   d.Set("enrollment", EncodeEnrollment(enrolled_template_id,
                                        (*enrollments)[enrolled_template_id]));
-  ResolveJavascriptCallback(base::Value(std::move(callback_id_)),
-                            base::Value(std::move(d)));
+  ResolveJavascriptCallback(base::Value(std::move(callback_id_)), d);
 }
 
 void SecurityKeysBioEnrollmentHandler::HandleDelete(
@@ -1118,7 +1106,7 @@
   result.Append(std::move(synced));
   result.Append(std::move(linked));
 
-  ResolveJavascriptCallback(callback_id, base::Value(std::move(result)));
+  ResolveJavascriptCallback(callback_id, result);
 }
 
 #if BUILDFLAG(IS_WIN)
@@ -1213,8 +1201,7 @@
     result = base::Value(std::move(passkeys));
   }
 
-  ResolveJavascriptCallback(base::Value(std::move(callback_id)),
-                            std::move(result));
+  ResolveJavascriptCallback(base::Value(std::move(callback_id)), result);
 }
 
 void PasskeysHandler::HandleDelete(const base::Value::List& args) {
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chrome/browser/ui/webui/settings/site_settings_handler.cc
index b25a3af..44d56ba 100644
--- a/chrome/browser/ui/webui/settings/site_settings_handler.cc
+++ b/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -288,7 +288,7 @@
   for (const auto& entry : site_group_map) {
     // eTLD+1 is the effective top level domain + 1.
     base::Value::Dict site_group;
-    site_group.Set(kEffectiveTopLevelDomainPlus1Name, base::Value(entry.first));
+    site_group.Set(kEffectiveTopLevelDomainPlus1Name, entry.first);
     bool has_installed_pwa = false;
     base::Value::List origin_list;
     for (const auto& origin_is_partitioned : entry.second) {
@@ -297,30 +297,28 @@
       base::Value::Dict origin_object;
       // If origin is placeholder, create a http ETLD+1 origin for it.
       if (origin == kPlaceholder) {
-        origin_object.Set("origin", base::Value(ConvertEtldToOrigin(
-                                        entry.first, /*secure=*/false)));
+        origin_object.Set("origin",
+                          ConvertEtldToOrigin(entry.first, /*secure=*/false));
       } else {
-        origin_object.Set("origin", base::Value(origin));
+        origin_object.Set("origin", origin);
       }
-      origin_object.Set("isPartitioned", base::Value(is_partitioned));
-      origin_object.Set(
-          "engagement",
-          base::Value(engagement_service->GetScore(GURL(origin))));
-      origin_object.Set("usage", base::Value(0));
-      origin_object.Set(kNumCookies, base::Value(0));
+      origin_object.Set("isPartitioned", is_partitioned);
+      origin_object.Set("engagement",
+                        engagement_service->GetScore(GURL(origin)));
+      origin_object.Set("usage", 0);
+      origin_object.Set(kNumCookies, 0);
 
       bool is_installed = installed_origins.contains(origin);
       if (is_installed)
         has_installed_pwa = true;
-      origin_object.Set(kIsInstalled, base::Value(is_installed));
+      origin_object.Set(kIsInstalled, is_installed);
 
-      origin_object.Set(
-          kHasPermissionSettings,
-          base::Value(base::Contains(origin_permission_set, origin)));
+      origin_object.Set(kHasPermissionSettings,
+                        base::Contains(origin_permission_set, origin));
       origin_list.Append(std::move(origin_object));
     }
-    site_group.Set(kHasInstalledPWA, base::Value(has_installed_pwa));
-    site_group.Set(kNumCookies, base::Value(0));
+    site_group.Set(kHasInstalledPWA, has_installed_pwa);
+    site_group.Set(kNumCookies, 0);
     site_group.Set(kOriginList, std::move(origin_list));
     if (first_party_sets.size()) {
       auto site = net::SchemefulSite(
@@ -911,7 +909,7 @@
 
   base::Value::Dict category;
   site_settings::GetContentCategorySetting(map, content_type, &category);
-  ResolveJavascriptCallback(callback_id, base::Value(std::move(category)));
+  ResolveJavascriptCallback(callback_id, category);
 }
 
 void SiteSettingsHandler::HandleGetAllSites(const base::Value::List& args) {
@@ -979,8 +977,7 @@
 
   send_sites_list_ = true;
 
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(result)));
+  ResolveJavascriptCallback(base::Value(callback_id), result);
 }
 
 void SiteSettingsHandler::HandleGetCategoryList(const base::Value::List& args) {
@@ -996,8 +993,7 @@
     result.Append(site_settings::ContentSettingsTypeToGroupName(content_type));
   }
 
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(result)));
+  ResolveJavascriptCallback(base::Value(callback_id), result);
 }
 
 void SiteSettingsHandler::HandleGetCookieSettingDescription(
@@ -1027,34 +1023,31 @@
   for (const auto& site_permissions : recent_site_permissions) {
     DCHECK(!site_permissions.settings.empty());
     base::Value::Dict recent_site;
-    recent_site.Set(site_settings::kOrigin,
-                    base::Value(site_permissions.origin.spec()));
-    recent_site.Set(site_settings::kIncognito,
-                    base::Value(site_permissions.incognito));
+    recent_site.Set(site_settings::kOrigin, site_permissions.origin.spec());
+    recent_site.Set(site_settings::kIncognito, site_permissions.incognito);
 
     base::Value::List permissions_list;
     for (const auto& p : site_permissions.settings) {
       base::Value::Dict recent_permission;
       recent_permission.Set(
           site_settings::kType,
-          base::Value(
-              site_settings::ContentSettingsTypeToGroupName(p.content_type)));
+
+          site_settings::ContentSettingsTypeToGroupName(p.content_type));
       recent_permission.Set(
           site_settings::kSetting,
-          base::Value(
-              content_settings::ContentSettingToString(p.content_setting)));
+
+          content_settings::ContentSettingToString(p.content_setting));
       recent_permission.Set(
           site_settings::kSource,
-          base::Value(
-              site_settings::SiteSettingSourceToString(p.setting_source)));
+
+          site_settings::SiteSettingSourceToString(p.setting_source));
       permissions_list.Append(std::move(recent_permission));
     }
     recent_site.Set(site_settings::kRecentPermissions,
                     std::move(permissions_list));
     result.Append(std::move(recent_site));
   }
-  ResolveJavascriptCallback(base::Value(callback_id),
-                            base::Value(std::move(result)));
+  ResolveJavascriptCallback(base::Value(callback_id), result);
 }
 
 base::Value::List SiteSettingsHandler::PopulateCookiesAndUsageData(
@@ -1070,11 +1063,12 @@
                             profile);
 
   // Merge the origin usage and cookies number into |list_value|.
-  for (base::Value& site_group : list_value) {
-    base::Value* origin_list = site_group.FindKey(kOriginList);
+  for (base::Value& item : list_value) {
+    base::Value::Dict& site_group = item.GetDict();
+    base::Value::List& origin_list = *site_group.FindList(kOriginList);
     int cookie_num = 0;
     const std::string& etld_plus1 =
-        site_group.FindKey(kEffectiveTopLevelDomainPlus1Name)->GetString();
+        *site_group.FindString(kEffectiveTopLevelDomainPlus1Name);
     const auto& etld_plus1_cookie_num_it =
         origin_cookie_map.find({etld_plus1, absl::nullopt});
     // Add the number of eTLD+1 scoped cookies.
@@ -1082,30 +1076,30 @@
       cookie_num = etld_plus1_cookie_num_it->second;
     // Iterate over the origins for the ETLD+1, and set their usage and cookie
     // numbers.
-    for (base::Value& origin_info : origin_list->GetListDeprecated()) {
-      const std::string& origin = origin_info.FindKey("origin")->GetString();
-      bool is_partitioned = origin_info.FindKey("isPartitioned")->GetBool();
+    for (base::Value& value : origin_list) {
+      base::Value::Dict& origin_info = value.GetDict();
+      const std::string* origin = origin_info.FindString("origin");
+      bool is_partitioned =
+          origin_info.FindBool("isPartitioned").value_or(false);
       if (!is_partitioned) {
         // Only unpartitioned storage has a size.
-        const auto& size_info_it = origin_size_map.find(origin);
+        const auto& size_info_it = origin_size_map.find(*origin);
         if (size_info_it != origin_size_map.end())
-          origin_info.SetKey(
-              "usage", base::Value(static_cast<double>(size_info_it->second)));
+          origin_info.Set("usage", static_cast<double>(size_info_it->second));
       }
-      GURL origin_url(origin);
+      GURL origin_url(*origin);
       const auto& origin_cookie_num_it = origin_cookie_map.find(
           {origin_url.host(),
            (is_partitioned ? absl::optional<std::string>(etld_plus1)
                            : absl::nullopt)});
       if (origin_cookie_num_it != origin_cookie_map.end()) {
-        origin_info.SetKey(kNumCookies,
-                           base::Value(origin_cookie_num_it->second));
+        origin_info.Set(kNumCookies, origin_cookie_num_it->second);
         // Add cookies numbers for origins that isn't an eTLD+1.
         if (origin_url.host() != etld_plus1 || is_partitioned)
           cookie_num += origin_cookie_num_it->second;
       }
     }
-    site_group.SetKey(kNumCookies, base::Value(cookie_num));
+    site_group.Set(kNumCookies, cookie_num);
   }
   return list_value;
 }
@@ -1113,7 +1107,7 @@
 void SiteSettingsHandler::OnStorageFetched() {
   AllowJavascript();
   FireWebUIListener("onStorageListFetched",
-                    base::Value(PopulateCookiesAndUsageData(profile_)));
+                    PopulateCookiesAndUsageData(profile_));
 }
 
 void SiteSettingsHandler::HandleGetFormattedBytes(
@@ -1157,7 +1151,7 @@
                                                /*incognito=*/true, &exceptions);
   }
 
-  ResolveJavascriptCallback(callback_id, base::Value(std::move(exceptions)));
+  ResolveJavascriptCallback(callback_id, exceptions);
 }
 
 void SiteSettingsHandler::HandleGetChooserExceptionList(
@@ -1174,7 +1168,7 @@
   base::Value::List exceptions =
       site_settings::GetChooserExceptionListFromProfile(profile_,
                                                         *chooser_type);
-  ResolveJavascriptCallback(callback_id, base::Value(std::move(exceptions)));
+  ResolveJavascriptCallback(callback_id, exceptions);
 }
 
 void SiteSettingsHandler::HandleGetOriginPermissions(
@@ -1184,7 +1178,7 @@
   CHECK_EQ(3U, args.size());
   const base::Value& callback_id = args[0];
   std::string origin = args[1].GetString();
-  base::Value::ConstListView types = args[2].GetListDeprecated();
+  const base::Value::List& types = args[2].GetList();
 
   // Note: Invalid URLs will just result in default settings being shown.
   const GURL origin_url(origin);
@@ -1221,7 +1215,7 @@
     exceptions.Append(std::move(raw_site_exception));
   }
 
-  ResolveJavascriptCallback(callback_id, base::Value(std::move(exceptions)));
+  ResolveJavascriptCallback(callback_id, exceptions);
 }
 
 void SiteSettingsHandler::HandleSetOriginPermissions(
@@ -1462,7 +1456,7 @@
   base::Value::Dict return_value;
   return_value.Set(kIsValidKey, base::Value(is_valid));
   return_value.Set(kReasonKey, base::Value(std::move(reason)));
-  ResolveJavascriptCallback(callback_id, base::Value(std::move(return_value)));
+  ResolveJavascriptCallback(callback_id, return_value);
 }
 
 void SiteSettingsHandler::HandleUpdateIncognitoStatus(
@@ -1551,8 +1545,7 @@
     zoom_levels_exceptions.Append(std::move(exception));
   }
 
-  FireWebUIListener("onZoomLevelsChanged",
-                    base::Value(std::move(zoom_levels_exceptions)));
+  FireWebUIListener("onZoomLevelsChanged", zoom_levels_exceptions);
 }
 
 void SiteSettingsHandler::HandleRemoveZoomLevel(const base::Value::List& args) {
@@ -1586,18 +1579,16 @@
   // Whether the block autoplay toggle should be checked.
   base::Value::Dict pref;
   pref.Set("value",
-           base::Value(
-               UnifiedAutoplayConfig::ShouldBlockAutoplay(profile_) &&
-               UnifiedAutoplayConfig::IsBlockAutoplayUserModifiable(profile_)));
+
+           UnifiedAutoplayConfig::ShouldBlockAutoplay(profile_) &&
+               UnifiedAutoplayConfig::IsBlockAutoplayUserModifiable(profile_));
   status.Set("pref", std::move(pref));
 
   // Whether the block autoplay toggle should be enabled.
   status.Set("enabled",
-             base::Value(UnifiedAutoplayConfig::IsBlockAutoplayUserModifiable(
-                 profile_)));
+             UnifiedAutoplayConfig::IsBlockAutoplayUserModifiable(profile_));
 
-  FireWebUIListener("onBlockAutoplayStatusChanged",
-                    base::Value(std::move(status)));
+  FireWebUIListener("onBlockAutoplayStatusChanged", status);
 }
 
 void SiteSettingsHandler::HandleSetBlockAutoplayEnabled(
diff --git a/chrome/browser/ui/webui/signin/enterprise_profile_welcome_handler_unittest.cc b/chrome/browser/ui/webui/signin/enterprise_profile_welcome_handler_unittest.cc
index 8b3b969a2..8606203 100644
--- a/chrome/browser/ui/webui/signin/enterprise_profile_welcome_handler_unittest.cc
+++ b/chrome/browser/ui/webui/signin/enterprise_profile_welcome_handler_unittest.cc
@@ -100,10 +100,10 @@
       GetParam().profile_creation_required_by_policy,
       /*show_link_data_option=*/true, mock_proceed_callback.Get());
 
-  base::ListValue args;
+  base::Value::List args;
   args.Append(GetParam().should_link_data);
   EXPECT_CALL(mock_proceed_callback, Run(GetParam().expected_choice));
-  web_ui()->HandleReceivedMessage("proceed", &args);
+  web_ui()->HandleReceivedMessage("proceed", args);
 }
 
 INSTANTIATE_TEST_SUITE_P(All,
diff --git a/chrome/browser/ui/webui/signin/inline_login_handler_chromeos_browsertest.cc b/chrome/browser/ui/webui/signin/inline_login_handler_chromeos_browsertest.cc
index a25820b..abe7b0fc 100644
--- a/chrome/browser/ui/webui/signin/inline_login_handler_chromeos_browsertest.cc
+++ b/chrome/browser/ui/webui/signin/inline_login_handler_chromeos_browsertest.cc
@@ -272,15 +272,15 @@
   }
 
   void CompleteConsentLogForChildUser(const std::string& secondary_email) {
-    base::ListValue call_args;
+    base::Value::List call_args;
     call_args.Append(secondary_email);
     call_args.Append(kToSVersion);
 
-    base::ListValue list_args;
+    base::Value::List list_args;
     list_args.Append(kConsentLoggedCallback);
     list_args.Append(std::move(call_args));
 
-    web_ui()->HandleReceivedMessage("consentLogged", &list_args);
+    web_ui()->HandleReceivedMessage("consentLogged", list_args);
   }
 
   ash::FakeChromeUserManager* GetFakeUserManager() const {
@@ -322,9 +322,9 @@
       ->AddObserver(&observer);
 
   // Call "completeLogin".
-  base::ListValue args;
+  base::Value::List args;
   args.Append(GetCompleteLoginArgs(kSecondaryAccount1Email));
-  web_ui()->HandleReceivedMessage(kCompleteLoginMessage, &args);
+  web_ui()->HandleReceivedMessage(kCompleteLoginMessage, args);
 
   if (GetDeviceAccountInfo().user_type ==
       user_manager::UserType::USER_TYPE_CHILD) {
@@ -350,9 +350,9 @@
       ->AddObserver(&observer);
 
   // Call "completeLogin".
-  base::ListValue args;
+  base::Value::List args;
   args.Append(GetCompleteLoginArgs(GetDeviceAccountInfo().email));
-  web_ui()->HandleReceivedMessage(kCompleteLoginMessage, &args);
+  web_ui()->HandleReceivedMessage(kCompleteLoginMessage, args);
 
   // Wait until account is added.
   base::RunLoop run_loop;
@@ -428,10 +428,9 @@
 
   const base::span<const base::Value> CallGetAccountsNotAvailableInArc() {
     // Call "getAccountsNotAvailableInArc".
-    base::Value args(base::Value::Type::LIST);
+    base::Value::List args;
     args.Append(kHandleFunctionName);
-    web_ui()->HandleReceivedMessage(kGetAccountsNotAvailableInArcMessage,
-                                    &base::Value::AsListValue(args));
+    web_ui()->HandleReceivedMessage(kGetAccountsNotAvailableInArcMessage, args);
     base::RunLoop().RunUntilIdle();
 
     const content::TestWebUI::CallData& call_data =
@@ -459,9 +458,9 @@
       &apps_availability_observer);
 
   // Call "completeLogin".
-  base::ListValue args;
+  base::Value::List args;
   args.Append(GetCompleteLoginArgs(kSecondaryAccount1Email));
-  web_ui()->HandleReceivedMessage(kCompleteLoginMessage, &args);
+  web_ui()->HandleReceivedMessage(kCompleteLoginMessage, args);
 
   if (GetDeviceAccountInfo().user_type ==
       user_manager::UserType::USER_TYPE_CHILD) {
@@ -500,9 +499,9 @@
       &apps_availability_observer);
 
   // Call "completeLogin".
-  base::ListValue args;
+  base::Value::List args;
   args.Append(GetCompleteLoginArgs(GetDeviceAccountInfo().email));
-  web_ui()->HandleReceivedMessage(kCompleteLoginMessage, &args);
+  web_ui()->HandleReceivedMessage(kCompleteLoginMessage, args);
 
   // Wait until account is added.
   base::RunLoop run_loop;
@@ -551,10 +550,9 @@
   EXPECT_TRUE(ValuesListContainAccount(result, kSecondaryAccount2Email));
 
   // Call "makeAvailableInArc".
-  base::Value args_1(base::Value::Type::LIST);
+  base::Value::List args_1;
   args_1.Append(ValuesListGetAccount(result, kSecondaryAccount2Email).value());
-  web_ui()->HandleReceivedMessage(kMakeAvailableInArcMessage,
-                                  &base::Value::AsListValue(args_1));
+  web_ui()->HandleReceivedMessage(kMakeAvailableInArcMessage, args_1);
 
   // Call "getAccountsNotAvailableInArc".
   const base::span<const base::Value> result_1 =
diff --git a/chrome/browser/ui/webui/signin/profile_customization_ui.cc b/chrome/browser/ui/webui/signin/profile_customization_ui.cc
index a4edb02..45172be68 100644
--- a/chrome/browser/ui/webui/signin/profile_customization_ui.cc
+++ b/chrome/browser/ui/webui/signin/profile_customization_ui.cc
@@ -49,7 +49,6 @@
        IDR_SIGNIN_PROFILE_CUSTOMIZATION_IMAGES_PROFILE_CUSTOMIZATION_ILLUSTRATION_SVG},
       {"images/profile_customization_illustration_dark.svg",
        IDR_SIGNIN_PROFILE_CUSTOMIZATION_IMAGES_PROFILE_CUSTOMIZATION_ILLUSTRATION_DARK_SVG},
-      {"signin_icons.js", IDR_SIGNIN_SIGNIN_ICONS_JS},
       {"signin_shared.css.js", IDR_SIGNIN_SIGNIN_SHARED_CSS_JS},
       {"signin_vars.css.js", IDR_SIGNIN_SIGNIN_VARS_CSS_JS},
   };
diff --git a/chrome/browser/ui/webui/signin/profile_picker_handler_unittest.cc b/chrome/browser/ui/webui/signin/profile_picker_handler_unittest.cc
index 31795c2..709ccb07 100644
--- a/chrome/browser/ui/webui/signin/profile_picker_handler_unittest.cc
+++ b/chrome/browser/ui/webui/signin/profile_picker_handler_unittest.cc
@@ -125,8 +125,8 @@
 
   void InitializeMainViewAndVerifyProfileList(
       const std::vector<ProfileAttributesEntry*>& ordered_profile_entries) {
-    base::ListValue empty_args;
-    web_ui()->HandleReceivedMessage("mainViewInitialize", &empty_args);
+    base::Value::List empty_args;
+    web_ui()->HandleReceivedMessage("mainViewInitialize", empty_args);
     VerifyProfileListWasPushed(ordered_profile_entries);
   }
 
@@ -312,8 +312,8 @@
   CompleteFacadeGetAccounts({});
 
   // Send message to the handler.
-  base::ListValue empty_args;
-  web_ui()->HandleReceivedMessage("getAvailableAccounts", &empty_args);
+  base::Value::List empty_args;
+  web_ui()->HandleReceivedMessage("getAvailableAccounts", empty_args);
 
   // Check that the handler replied.
   ASSERT_TRUE(!web_ui()->call_data().empty());
@@ -345,8 +345,8 @@
 
   // ****** No accounts syncing in any profile: return all.
   // Send message to the handler.
-  base::ListValue empty_args;
-  web_ui()->HandleReceivedMessage("getAvailableAccounts", &empty_args);
+  base::Value::List empty_args;
+  web_ui()->HandleReceivedMessage("getAvailableAccounts", empty_args);
 
   // Check that the handler replied.
   ASSERT_TRUE(!web_ui()->call_data().empty());
@@ -360,7 +360,7 @@
   secondary->SetAuthInfo(kGaiaId1, u"example1@gmail.com",
                          /*is_consented_primary_account=*/true);
   // Send message to the handler.
-  web_ui()->HandleReceivedMessage("getAvailableAccounts", &empty_args);
+  web_ui()->HandleReceivedMessage("getAvailableAccounts", empty_args);
 
   // Check that the handler replied.
   ASSERT_TRUE(!web_ui()->call_data().empty());
@@ -404,8 +404,8 @@
   CompleteFacadeGetAccounts({account1, account2});
 
   // Send message to the handler.
-  base::ListValue empty_args;
-  web_ui()->HandleReceivedMessage("getAvailableAccounts", &empty_args);
+  base::Value::List empty_args;
+  web_ui()->HandleReceivedMessage("getAvailableAccounts", empty_args);
 
   // Check that the handler replied.
   ASSERT_TRUE(!web_ui()->call_data().empty());
@@ -453,10 +453,10 @@
 
   // Request profile creation with the existing account.
   ProfileWaiter profile_waiter;
-  base::ListValue args;
+  base::Value::List args;
   args.Append(/*color=*/base::Value());
   args.Append(/*gaiaId=*/kGaiaId);
-  web_ui()->HandleReceivedMessage("selectAccountLacros", &args);
+  web_ui()->HandleReceivedMessage("selectAccountLacros", args);
 
   // Check profile creation.
   Profile* new_profile = profile_waiter.WaitForProfileAdded();
@@ -518,10 +518,10 @@
 
   // Request profile creation.
   ProfileWaiter profile_waiter;
-  base::ListValue args;
+  base::Value::List args;
   args.Append(/*color=*/base::Value());
   args.Append(/*gaiaId=*/base::Value(base::Value::Type::STRING));
-  web_ui()->HandleReceivedMessage("selectAccountLacros", &args);
+  web_ui()->HandleReceivedMessage("selectAccountLacros", args);
 
   // Check profile creation.
   Profile* new_profile = profile_waiter.WaitForProfileAdded();
@@ -588,8 +588,8 @@
   CompleteFacadeGetAccounts({});
 
   // Send message to the handler.
-  base::ListValue empty_args;
-  web_ui()->HandleReceivedMessage("getAvailableAccounts", &empty_args);
+  base::Value::List empty_args;
+  web_ui()->HandleReceivedMessage("getAvailableAccounts", empty_args);
 
   // Check that the handler replied.
   ASSERT_TRUE(!web_ui()->call_data().empty());
@@ -617,8 +617,8 @@
 
   // ****** No accounts assigned to "Secondary": return all.
   // Send message to the handler.
-  base::ListValue empty_args;
-  web_ui()->HandleReceivedMessage("getAvailableAccounts", &empty_args);
+  base::Value::List empty_args;
+  web_ui()->HandleReceivedMessage("getAvailableAccounts", empty_args);
 
   // Check that the handler replied.
   ASSERT_TRUE(!web_ui()->call_data().empty());
@@ -634,7 +634,7 @@
           ->GetProfileAttributesWithPath(GetWebUIProfile()->GetPath());
   profile_entry->SetGaiaIds({kGaiaId1});
   // Send message to the handler.
-  web_ui()->HandleReceivedMessage("getAvailableAccounts", &empty_args);
+  web_ui()->HandleReceivedMessage("getAvailableAccounts", empty_args);
 
   // Check that the handler replied.
   ASSERT_TRUE(!web_ui()->call_data().empty());
@@ -689,9 +689,9 @@
 TEST_F(ProfilePickerHandlerInUserProfileTest,
        HandleGetNewProfileSuggestedThemeInfo_Default) {
   // Send message to the handler.
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kTestCallbackId);
-  web_ui()->HandleReceivedMessage("getNewProfileSuggestedThemeInfo", &args);
+  web_ui()->HandleReceivedMessage("getNewProfileSuggestedThemeInfo", args);
 
   // Check that the handler replied correctly.
   const base::Value& theme_info = GetThemeInfoReply();
@@ -706,9 +706,9 @@
   theme_service->BuildAutogeneratedThemeFromColor(SK_ColorRED);
 
   // Send message to the handler.
-  base::ListValue args;
+  base::Value::List args;
   args.Append(kTestCallbackId);
-  web_ui()->HandleReceivedMessage("getNewProfileSuggestedThemeInfo", &args);
+  web_ui()->HandleReceivedMessage("getNewProfileSuggestedThemeInfo", args);
 
   // Check that the handler replied correctly.
   const base::Value& theme_info = GetThemeInfoReply();
@@ -753,10 +753,10 @@
           });
 
   // Request account addition.
-  base::ListValue args;
+  base::Value::List args;
   args.Append(/*color=*/base::Value());
   args.Append(/*gaiaId=*/base::Value(base::Value::Type::STRING));
-  web_ui()->HandleReceivedMessage("selectAccountLacros", &args);
+  web_ui()->HandleReceivedMessage("selectAccountLacros", args);
 }
 
 #endif  //  BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 8bc4630..bf3803f 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1660175924-af8d261529a1f3581ef2316de9f20b8dbd3c19a4.profdata
+chrome-linux-main-1660219080-5c2d21bf4dd331c9b4e976e9165d27d27759ab52.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index cb19758..2d03ccd9 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1660152362-f71b407188825fc9d5b726090d3fc94f8f5dd990.profdata
+chrome-mac-arm-main-1660219080-a5810d2f27359bada7076a460c32c05eaf48902f.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 604b44c..c1f08ae3 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1660175924-22c10a6754b49eb15bbf105b9721a072152c3833.profdata
+chrome-mac-main-1660193600-2b7fa3816328527a7e00a736424cbd7cbf96c851.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index cfcfe32..4b30e928 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1660165058-c50af8c23e747b840dfa26e43af713b210a94c0c.profdata
+chrome-win32-main-1660208231-bda3a7165fd2741122c6552bad163d6fa6dda599.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index ce4be0b2..9c59abac 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1660175924-fe46b035376fce8a4d732c4ceefa5d4ef5d077da.profdata
+chrome-win64-main-1660208231-1302a399e8b23f6be0d4ddfc587838d830ea73b6.profdata
diff --git a/chrome/common/chromeos/extensions/api/_api_features.json b/chrome/common/chromeos/extensions/api/_api_features.json
index e18ae7c..851de757 100644
--- a/chrome/common/chromeos/extensions/api/_api_features.json
+++ b/chrome/common/chromeos/extensions/api/_api_features.json
@@ -14,7 +14,8 @@
       "blessed_extension"
     ],
     "platforms": [
-      "chromeos"
+      "chromeos",
+      "lacros"
     ],
     "channel": "stable"
   },
diff --git a/chrome/common/chromeos/extensions/api/api_sources.gni b/chrome/common/chromeos/extensions/api/api_sources.gni
index c7d2ae8..ac91f8a 100644
--- a/chrome/common/chromeos/extensions/api/api_sources.gni
+++ b/chrome/common/chromeos/extensions/api/api_sources.gni
@@ -8,11 +8,10 @@
 
 assert(enable_extensions)
 
-schema_sources_ = [ "telemetry.idl" ]
-
-if (is_chromeos_ash) {
-  schema_sources_ += [ "diagnostics.idl" ]
-}
+schema_sources_ = [
+  "diagnostics.idl",
+  "telemetry.idl",
+]
 
 chromeos_system_extensions_api_schema_sources =
     get_path_info(schema_sources_, "abspath")
diff --git a/chrome/installer/util/experiment_storage.cc b/chrome/installer/util/experiment_storage.cc
index be6d9c40..22868759 100644
--- a/chrome/installer/util/experiment_storage.cc
+++ b/chrome/installer/util/experiment_storage.cc
@@ -14,6 +14,8 @@
 #include "base/base64.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
+#include "base/check.h"
+#include "base/debug/crash_logging.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/utf_string_conversions.h"
@@ -256,8 +258,15 @@
 
 // ExperimentStorage -----------------------------------------------------------
 
-ExperimentStorage::ExperimentStorage()
-    : mutex_(::CreateMutex(nullptr, FALSE, GetMutexName().c_str())) {}
+ExperimentStorage::ExperimentStorage() {
+  // Diagnose failure to create mutex; see https://crbug.com/1351849.
+  const auto mutex_name = GetMutexName();
+  SCOPED_CRASH_KEY_STRING256("ExperimentStorage", "mutex_name",
+                             base::WideToASCII(mutex_name));
+  HANDLE mutex = ::CreateMutex(nullptr, FALSE, mutex_name.c_str());
+  PCHECK(mutex) << "Failed to create ExperimentStorage mutex";
+  mutex_.Set(mutex);
+}
 
 ExperimentStorage::~ExperimentStorage() {}
 
diff --git a/chrome/renderer/autofill/form_autofill_browsertest.cc b/chrome/renderer/autofill/form_autofill_browsertest.cc
index 8d678a96..d8150c2ae 100644
--- a/chrome/renderer/autofill/form_autofill_browsertest.cc
+++ b/chrome/renderer/autofill/form_autofill_browsertest.cc
@@ -11,6 +11,7 @@
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
@@ -2349,6 +2350,31 @@
   EXPECT_FORM_FIELD_DATA_EQUALS(expected, result2);
 }
 
+// <label for=fieldId> elements are correctly assigned to their inputs. Multiple
+// labels are separated with a space.
+TEST_F(FormAutofillTest, WebFormControlElementToFormField_LabelFor) {
+  base::test::ScopedFeatureList improved_label_for_inference;
+  improved_label_for_inference.InitAndEnableFeature(
+      features::kAutofillImprovedLabelForInference);
+
+  LoadHTML(R"(
+    <label for=fieldId>foo</label>
+    <label for=fieldId>bar</label>
+    <input id=fieldId>
+  )");
+  ASSERT_NE(GetMainFrame(), nullptr);
+
+  base::HistogramTester histogram_tester;
+  FormFieldData form_field_data;
+  WebFormControlElementToFormField(FormRendererId(),
+                                   GetFormControlElementById("fieldId"),
+                                   nullptr, EXTRACT_NONE, &form_field_data);
+  EXPECT_EQ(form_field_data.label, u"foo bar");
+  EXPECT_THAT(
+      histogram_tester.GetAllSamples(kAssignedLabelSourceHistogram),
+      testing::UnorderedElementsAre(base::Bucket(AssignedLabelSource::kId, 2)));
+}
+
 // We should be able to extract a text field with autocomplete="off".
 TEST_F(FormAutofillTest, WebFormControlElementToFormFieldAutocompleteOff) {
   LoadHTML("<INPUT type='text' id='element' value='value'"
diff --git a/chromeos/crosapi/mojom/crosapi.mojom b/chromeos/crosapi/mojom/crosapi.mojom
index 1c153d0..68c4d8cf 100644
--- a/chromeos/crosapi/mojom/crosapi.mojom
+++ b/chromeos/crosapi/mojom/crosapi.mojom
@@ -26,6 +26,7 @@
 import "chromeos/crosapi/mojom/device_attributes.mojom";
 import "chromeos/crosapi/mojom/device_oauth2_token_service.mojom";
 import "chromeos/crosapi/mojom/device_settings_service.mojom";
+import "chromeos/crosapi/mojom/diagnostics_service.mojom";
 import "chromeos/crosapi/mojom/digital_goods.mojom";
 import "chromeos/crosapi/mojom/dlp.mojom";
 import "chromeos/crosapi/mojom/document_scan.mojom";
@@ -125,8 +126,8 @@
 // please note the milestone when you added it, to help us reason about
 // compatibility between the client applications and older ash-chrome binaries.
 //
-// Next version: 95
-// Next method id: 99
+// Next version: 96
+// Next method id: 100
 [Stable, Uuid="8b79c34f-2bf8-4499-979a-b17cac522c1e",
  RenamedFrom="crosapi.mojom.AshChromeService"]
 interface Crosapi {
@@ -260,6 +261,12 @@
   [MinVersion=55] BindDeviceSettingsService@59(
     pending_receiver<DeviceSettingsService> receiver);
 
+  // Binds the diagnostics service to allow Lacros to initiate diagnostics
+  // routines from Ash.
+  // Added in M106.
+  [MinVersion=95] BindDiagnosticsService@99(
+    pending_receiver<crosapi.mojom.DiagnosticsService> receiver);
+
   // Added in M104.
   [MinVersion=76] BindDigitalGoodsFactory@79(
     pending_receiver<DigitalGoodsFactory> receiver);
diff --git a/chromeos/lacros/lacros_service.cc b/chromeos/lacros/lacros_service.cc
index f8b1c5a6..6da1d10b 100644
--- a/chromeos/lacros/lacros_service.cc
+++ b/chromeos/lacros/lacros_service.cc
@@ -35,6 +35,7 @@
 #include "chromeos/crosapi/mojom/desk_template.mojom.h"
 #include "chromeos/crosapi/mojom/device_oauth2_token_service.mojom.h"
 #include "chromeos/crosapi/mojom/device_settings_service.mojom.h"
+#include "chromeos/crosapi/mojom/diagnostics_service.mojom.h"
 #include "chromeos/crosapi/mojom/digital_goods.mojom.h"
 #include "chromeos/crosapi/mojom/dlp.mojom.h"
 #include "chromeos/crosapi/mojom/document_scan.mojom.h"
@@ -292,6 +293,9 @@
       &Crosapi::BindDeviceSettingsService,
       Crosapi::MethodMinVersions::kBindDeviceSettingsServiceMinVersion>();
   ConstructRemote<
+      crosapi::mojom::DiagnosticsService, &Crosapi::BindDiagnosticsService,
+      Crosapi::MethodMinVersions::kBindDiagnosticsServiceMinVersion>();
+  ConstructRemote<
       crosapi::mojom::DigitalGoodsFactory, &Crosapi::BindDigitalGoodsFactory,
       Crosapi::MethodMinVersions::kBindDigitalGoodsFactoryMinVersion>();
   ConstructRemote<crosapi::mojom::Dlp, &Crosapi::BindDlp,
diff --git a/components/accuracy_tips/accuracy_service.cc b/components/accuracy_tips/accuracy_service.cc
index 9d3a2a8..daab3b3 100644
--- a/components/accuracy_tips/accuracy_service.cc
+++ b/components/accuracy_tips/accuracy_service.cc
@@ -111,11 +111,11 @@
                                           AccuracyCheckCallback callback) {
   DCHECK(ui_task_runner_->RunsTasksInCurrentSequence());
 
-  const base::Value* last_interactions =
-      pref_service_->Get(GetPreviousInteractionsPrefName(disable_ui_));
+  const base::Value::List& last_interactions =
+      pref_service_->GetValueList(GetPreviousInteractionsPrefName(disable_ui_));
   const base::Value opt_out_value(
       static_cast<int>(AccuracyTipInteraction::kOptOut));
-  if (base::Contains(last_interactions->GetListDeprecated(), opt_out_value)) {
+  if (base::Contains(last_interactions, opt_out_value)) {
     return std::move(callback).Run(AccuracyTipStatus::kOptOut);
   }
 
@@ -162,8 +162,7 @@
   }
 
   bool show_opt_out =
-      pref_service_->GetList(GetPreviousInteractionsPrefName(disable_ui_))
-          ->GetListDeprecated()
+      pref_service_->GetValueList(GetPreviousInteractionsPrefName(disable_ui_))
           .size() >= static_cast<size_t>(features::kNumIgnorePrompts.Get());
 
   url_for_last_shown_tip_ = web_contents->GetLastCommittedURL();
@@ -182,10 +181,9 @@
 
 void AccuracyService::MaybeShowSurvey() {
   if (CanShowSurvey()) {
-    auto* interactions_list =
-        pref_service_->GetList(GetPreviousInteractionsPrefName(disable_ui_));
-    const int last_interaction =
-        interactions_list->GetListDeprecated().back().GetInt();
+    const auto& interactions_list = pref_service_->GetValueList(
+        GetPreviousInteractionsPrefName(disable_ui_));
+    const int last_interaction = interactions_list.back().GetInt();
     const bool ukm_enabled = pref_service_->GetBoolean(
         unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled);
     std::string url_parameter_for_hats =
@@ -289,8 +287,7 @@
     return false;
 
   int interactions_count =
-      pref_service_->GetList(GetPreviousInteractionsPrefName(disable_ui_))
-          ->GetListDeprecated()
+      pref_service_->GetValueList(GetPreviousInteractionsPrefName(disable_ui_))
           .size();
   return interactions_count >= features::kMinPromptCountRequiredForSurvey.Get();
 }
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc
index 216d945..c5fb8a7 100644
--- a/components/autofill/content/renderer/form_autofill_util.cc
+++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -1297,17 +1297,6 @@
   }
 };
 
-// Autofill supports assigning <label for=x> tags to inputs if x its id/name,
-// or the id/name of a shadow host element containing the input.
-// This enum is used to track how often each case occurs in practise.
-enum class AssignedLabelSource {
-  kId = 0,
-  kName = 1,
-  kShadowHostId = 2,
-  kShadowHostName = 3,
-  kMaxValue = kShadowHostName,
-};
-
 // Searches |field_set| for a unique field with name |field_name|. If there is
 // none or more than one field with that name, the fields' shadow hosts' name
 // and id attributes are tested, and the first match is returned. Returns
@@ -1390,11 +1379,7 @@
     if (!field_data->label.empty() && !label_text.empty())
       field_data->label += u" ";
     field_data->label += label_text;
-    // This temporary histogram is emitted inline, because browser files like
-    // AutofillMetrics cannot be included here.
-    // TODO(crbug.com/1339277): Remove.
-    base::UmaHistogramEnumeration("Autofill.LabelInference.AssignedLabelSource",
-                                  label_source);
+    base::UmaHistogramEnumeration(kAssignedLabelSourceHistogram, label_source);
   }
 }
 
@@ -1497,7 +1482,8 @@
   }
 
   // Extracts field labels from the <label for="..."> tags.
-  {
+  if (!base::FeatureList::IsEnabled(
+          features::kAutofillImprovedLabelForInference)) {
     std::vector<std::pair<FormFieldData*, ShadowFieldData>> items;
     DCHECK_EQ(form->fields.size(), shadow_fields.size());
     for (size_t i = 0; i < form->fields.size(); i++) {
@@ -1642,6 +1628,22 @@
   return autocomplete_attribute;
 }
 
+// Returns the concatenated label text of all labels assigned to the `element`
+// using <label for=`element.GetIdAttribute()`>, separated by a space.
+std::u16string GetAssignedLabel(const WebFormControlElement& element) {
+  std::u16string concatenated_labels;
+  for (const auto& label : element.Labels()) {
+    if (auto label_text = FindChildText(label); !label_text.empty()) {
+      if (!concatenated_labels.empty())
+        concatenated_labels.push_back(' ');
+      concatenated_labels.append(std::move(label_text));
+      base::UmaHistogramEnumeration(kAssignedLabelSourceHistogram,
+                                    AssignedLabelSource::kId);
+    }
+  }
+  return concatenated_labels;
+}
+
 void FindFormElementUpShadowRoots(const WebElement& element,
                                   WebFormElement* found_form_element) {
   // If we are in shadowdom, then look to see if the host(s) are inside a form
@@ -1951,6 +1953,10 @@
   field->form_control_ax_id = element.GetAxId();
   field->form_control_type = element.FormControlTypeForAutofill().Utf8();
   field->autocomplete_attribute = GetAutocompleteAttribute(element);
+  if (base::FeatureList::IsEnabled(
+          features::kAutofillImprovedLabelForInference)) {
+    field->label = GetAssignedLabel(element);
+  }
   if (base::EqualsCaseInsensitiveASCII(element.GetAttribute(*kRole).Utf16(),
                                        "presentation")) {
     field->role = FormFieldData::RoleAttribute::kPresentation;
diff --git a/components/autofill/content/renderer/form_autofill_util.h b/components/autofill/content/renderer/form_autofill_util.h
index 414795a3..0c2036b 100644
--- a/components/autofill/content/renderer/form_autofill_util.h
+++ b/components/autofill/content/renderer/form_autofill_util.h
@@ -73,6 +73,22 @@
                                  // kMaxDataLength.
 };
 
+// Autofill supports assigning <label for=x> tags to inputs if x its id/name,
+// or the id/name of a shadow host element containing the input.
+// This enum is used to track how often each case occurs in practise.
+enum class AssignedLabelSource {
+  kId = 0,
+  kName = 1,
+  kShadowHostId = 2,
+  kShadowHostName = 3,
+  kMaxValue = kShadowHostName,
+};
+// This temporary histogram is emitted inline, because browser files like
+// AutofillMetrics cannot be included here.
+// TODO(crbug.com/1339277): Remove.
+inline constexpr char kAssignedLabelSourceHistogram[] =
+    "Autofill.LabelInference.AssignedLabelSource";
+
 // Indicates if an iframe |element| is considered actually visible to the user.
 //
 // This function is not intended to implement a perfect visibility check. It
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn
index fdc27af..18e22473 100644
--- a/components/autofill/core/browser/BUILD.gn
+++ b/components/autofill/core/browser/BUILD.gn
@@ -861,6 +861,7 @@
     "payments/virtual_card_enrollment_manager_unittest.cc",
     "payments/virtual_card_enrollment_strike_database_unittest.cc",
     "payments/wait_for_signal_or_timeout_unittest.cc",
+    "personal_data_manager_cleaner_unittest.cc",
     "personal_data_manager_test_base.cc",
     "personal_data_manager_test_base.h",
     "personal_data_manager_unittest.cc",
diff --git a/components/autofill/core/browser/autofill_test_utils.cc b/components/autofill/core/browser/autofill_test_utils.cc
index 4d85855..8d74afe8 100644
--- a/components/autofill/core/browser/autofill_test_utils.cc
+++ b/components/autofill/core/browser/autofill_test_utils.cc
@@ -573,15 +573,6 @@
   return credit_card;
 }
 
-CreditCard GetMaskedServerCardWithInvalidNickname() {
-  CreditCard credit_card(CreditCard::MASKED_SERVER_CARD, "c789");
-  test::SetCreditCardInfo(&credit_card, "Test user", "1111" /* Visa */,
-                          NextMonth().c_str(), NextYear().c_str(), "1");
-  credit_card.SetNetworkForMaskedCard(kVisaCard);
-  credit_card.SetNickname(u"Invalid nickname which is too long");
-  return credit_card;
-}
-
 CreditCard GetFullServerCard() {
   CreditCard credit_card(CreditCard::FULL_SERVER_CARD, "c123");
   test::SetCreditCardInfo(&credit_card, "Full Carter",
diff --git a/components/autofill/core/browser/autofill_test_utils.h b/components/autofill/core/browser/autofill_test_utils.h
index 2d5dda8e..ecb2ada0 100644
--- a/components/autofill/core/browser/autofill_test_utils.h
+++ b/components/autofill/core/browser/autofill_test_utils.h
@@ -228,7 +228,6 @@
 CreditCard GetMaskedServerCardWithLegacyId();
 CreditCard GetMaskedServerCardAmex();
 CreditCard GetMaskedServerCardWithNickname();
-CreditCard GetMaskedServerCardWithInvalidNickname();
 
 // Returns a full server card full of dummy info.
 CreditCard GetFullServerCard();
diff --git a/components/autofill/core/browser/data_model/credit_card_unittest.cc b/components/autofill/core/browser/data_model/credit_card_unittest.cc
index b237991..ebfcc92 100644
--- a/components/autofill/core/browser/data_model/credit_card_unittest.cc
+++ b/components/autofill/core/browser/data_model/credit_card_unittest.cc
@@ -334,6 +334,49 @@
       credit_card.CardIdentifierStringForAutofillDisplay());
 }
 
+// Test that customized nickname takes precedence over credit card's nickname.
+TEST(CreditCardTest,
+     CardIdentifierStringsForAutofillDisplay_WithCustomizedNickname) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeature(
+      features::kAutofillEnableCardProductName);
+
+  std::u16string customized_nickname = u"My grocery shopping Visa card";
+
+  CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
+  test::SetCreditCardInfo(&credit_card, "John Dillinger",
+                          "5105 1051 0510 5100" /* Mastercard */, "01", "2020",
+                          "1");
+  credit_card.SetNickname(u"My Visa Card");
+  credit_card.set_product_description(u"ABC bank XYZ card");
+  EXPECT_TRUE(credit_card.HasNonEmptyValidNickname());
+  EXPECT_EQ(
+      customized_nickname +
+          UTF8ToUTF16(std::string("  ") +
+                      test::ObfuscatedCardDigitsAsUTF8("5100")),
+      credit_card.CardIdentifierStringForAutofillDisplay(customized_nickname));
+}
+
+// Test that the card number is formatted as per the obfuscation length.
+TEST(CreditCardTest,
+     CardIdentifierStringsForAutofillDisplay_WithObfuscationLength) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeature(
+      features::kAutofillEnableCardProductName);
+
+  int obfuscation_length = 2;
+
+  CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
+  test::SetCreditCardInfo(&credit_card, "John Dillinger",
+                          "5105 1051 0510 5100" /* Mastercard */, "01", "2020",
+                          "1");
+  EXPECT_EQ(
+      UTF8ToUTF16(std::string("Mastercard  ") +
+                  test::ObfuscatedCardDigitsAsUTF8("5100", obfuscation_length)),
+      credit_card.CardIdentifierStringForAutofillDisplay(u"",
+                                                         obfuscation_length));
+}
+
 TEST(CreditCardTest, AssignmentOperator) {
   CreditCard a(base::GenerateGUID(), test::kEmptyOrigin);
   test::SetCreditCardInfo(&a, "John Dillinger", "123456789012", "01", "2010",
diff --git a/components/autofill/core/browser/form_data_importer_unittest.cc b/components/autofill/core/browser/form_data_importer_unittest.cc
index 13423781..ec707e5 100644
--- a/components/autofill/core/browser/form_data_importer_unittest.cc
+++ b/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -1208,7 +1208,7 @@
 
   // Assign the address field another section than the other fields.
   form_structure->field(4)->section.SetPrefixFromAutocomplete(
-      "another_section", HtmlFieldMode::HTML_MODE_NONE);
+      {.section = "another_section", .mode = HtmlFieldMode::HTML_MODE_NONE});
 
   ImportAddressProfileAndVerifyImportOfDefaultProfile(*form_structure);
 }
diff --git a/components/autofill/core/browser/form_parsing/form_field.cc b/components/autofill/core/browser/form_parsing/form_field.cc
index b031fe0..1dbf810 100644
--- a/components/autofill/core/browser/form_parsing/form_field.cc
+++ b/components/autofill/core/browser/form_parsing/form_field.cc
@@ -15,6 +15,7 @@
 #include "base/feature_list.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
 #include "components/autofill/core/browser/autofill_field.h"
 #include "components/autofill/core/browser/autofill_regexes.h"
 #include "components/autofill/core/browser/autofill_type.h"
@@ -31,6 +32,7 @@
 #include "components/autofill/core/browser/form_parsing/price_field.h"
 #include "components/autofill/core/browser/form_parsing/search_field.h"
 #include "components/autofill/core/browser/form_parsing/travel_field.h"
+#include "components/autofill/core/browser/form_processing/autocomplete_attribute_processing_util.h"
 #include "components/autofill/core/browser/form_structure.h"
 #include "components/autofill/core/browser/logging/log_manager.h"
 #include "components/autofill/core/common/autofill_constants.h"
@@ -117,6 +119,13 @@
   ParseFormFieldsPass(SearchField::Parse, processed_fields, field_candidates,
                       page_language, pattern_source, log_manager);
 
+  // Deduce `field_candidates` for the `processed_fields` by parsing their
+  // `parsable_name()` as an autocomplete attribute.
+  if (base::FeatureList::IsEnabled(
+          features::kAutofillParseNameAsAutocompleteType)) {
+    ParseUsingAutocompleteAttributes(processed_fields, field_candidates);
+  }
+
   size_t fillable_fields = 0;
   if (base::FeatureList::IsEnabled(features::kAutofillFixFillableFieldTypes)) {
     for (const auto& [field_id, candidates] : field_candidates) {
@@ -495,4 +504,21 @@
   return field_type == MERCHANT_PROMO_CODE;
 }
 
+// static
+void FormField::ParseUsingAutocompleteAttributes(
+    const std::vector<AutofillField*>& fields,
+    FieldCandidatesMap& field_candidates) {
+  for (const AutofillField* field : fields) {
+    HtmlFieldType html_type = FieldTypeFromAutocompleteAttributeValue(
+        base::UTF16ToUTF8(field->parseable_name()), *field);
+    // The HTML_MODE is irrelevant when converting to a ServerFieldType.
+    ServerFieldType type =
+        AutofillType(html_type, HTML_MODE_NONE).GetStorableType();
+    if (type != UNKNOWN_TYPE) {
+      AddClassification(field, type, kBaseAutocompleteParserScore,
+                        field_candidates);
+    }
+  }
+}
+
 }  // namespace autofill
diff --git a/components/autofill/core/browser/form_parsing/form_field.h b/components/autofill/core/browser/form_parsing/form_field.h
index c926c1df..0404742 100644
--- a/components/autofill/core/browser/form_parsing/form_field.h
+++ b/components/autofill/core/browser/form_parsing/form_field.h
@@ -104,6 +104,7 @@
   static constexpr float kBaseNameParserScore = 0.9f;
   static constexpr float kBaseMerchantPromoCodeParserScore = 0.85f;
   static constexpr float kBaseSearchParserScore = 0.8f;
+  static constexpr float kBaseAutocompleteParserScore = 0.05f;
 
   // Only derived classes may instantiate.
   FormField() = default;
@@ -233,6 +234,12 @@
                                   const LanguageCode& page_language,
                                   PatternSource pattern_source,
                                   LogManager* log_manager);
+
+  // Interpret the fields' `parsable_name()` (id or name attribute) as an
+  // autocomplete type and classify them by it. E.g. <input id=given-name>.
+  static void ParseUsingAutocompleteAttributes(
+      const std::vector<AutofillField*>& fields,
+      FieldCandidatesMap& field_candidates);
 };
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/form_parsing/form_field_unittest.cc b/components/autofill/core/browser/form_parsing/form_field_unittest.cc
index eb23dc9f..5292514 100644
--- a/components/autofill/core/browser/form_parsing/form_field_unittest.cc
+++ b/components/autofill/core/browser/form_parsing/form_field_unittest.cc
@@ -157,6 +157,21 @@
   }
 }
 
+// Tests that the `parseable_name()` is parsed as an autocomplete type.
+TEST_P(FormFieldTest, ParseNameAsAutocompleteType) {
+  base::test::ScopedFeatureList autocomplete_feature;
+  autocomplete_feature.InitAndEnableFeature(
+      features::kAutofillParseNameAsAutocompleteType);
+
+  AddTextFormFieldData("given-name", "", NAME_FIRST);
+  AddTextFormFieldData("family-name", "", NAME_LAST);
+  AddTextFormFieldData("cc-exp-month", "", CREDIT_CARD_EXP_MONTH);
+  // The label is not parsed as an autocomplete type.
+  AddTextFormFieldData("", "cc-exp-month", UNKNOWN_TYPE);
+  EXPECT_EQ(3, ParseFormFields());
+  TestClassificationExpectations();
+}
+
 // Test that the parseable label is used when the feature is enabled.
 TEST_P(FormFieldTest, TestParseableLabels) {
   AddTextFormFieldData("", "not a parseable label", UNKNOWN_TYPE);
diff --git a/components/autofill/core/browser/form_processing/autocomplete_attribute_processing_util.cc b/components/autofill/core/browser/form_processing/autocomplete_attribute_processing_util.cc
index 5a24c39..38c9829 100644
--- a/components/autofill/core/browser/form_processing/autocomplete_attribute_processing_util.cc
+++ b/components/autofill/core/browser/form_processing/autocomplete_attribute_processing_util.cc
@@ -137,6 +137,7 @@
       base::MakeFixedFlatMap<base::StringPiece, HtmlFieldType>({
           {"address", HTML_TYPE_STREET_ADDRESS},
           {"coupon-code", HTML_TYPE_MERCHANT_PROMO_CODE},
+          // TODO(crbug.com/1351760): Investigate if this mapping makes sense.
           {"username", HTML_TYPE_EMAIL},
       });
 
@@ -182,9 +183,8 @@
   return MatchesRegex<kRegex>(base::UTF8ToUTF16(value));
 }
 
-// Returns the Chrome Autofill-supported field type corresponding to a given
-// autocomplete `value`, if there is one, in the context of the given
-// `field`.
+}  // namespace
+
 HtmlFieldType FieldTypeFromAutocompleteAttributeValue(
     std::string value,
     const AutofillField& field) {
@@ -220,8 +220,6 @@
              : HTML_TYPE_UNRECOGNIZED;
 }
 
-}  // namespace
-
 absl::optional<AutocompleteParsingResult> ParseAutocompleteAttribute(
     const AutofillField& field) {
   std::vector<std::string> tokens =
diff --git a/components/autofill/core/browser/form_processing/autocomplete_attribute_processing_util.h b/components/autofill/core/browser/form_processing/autocomplete_attribute_processing_util.h
index 2dc88ce..352bbc97 100644
--- a/components/autofill/core/browser/form_processing/autocomplete_attribute_processing_util.h
+++ b/components/autofill/core/browser/form_processing/autocomplete_attribute_processing_util.h
@@ -40,6 +40,16 @@
 // currently ignored by Autofill.
 bool ShouldIgnoreAutocompleteAttribute(base::StringPiece autocomplete);
 
+// Parses `value` as an HTML field type and converts it to the corresponding
+// HtmlFieldType, if it is supposed by Autofill. Rationalization based on the
+// `field` is done.
+// HTML_TYPE_UNSPECIFIED is returned if `value` is empty, or if `value` is
+// supposed to be ignored by `kAutofillIgnoreUnmappableAutocompleteValues`.
+// Otherwise HTML_TYPE_UNRECOGNIZED is returned.
+HtmlFieldType FieldTypeFromAutocompleteAttributeValue(
+    std::string value,
+    const AutofillField& field);
+
 }  // namespace autofill
 
 #endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_FORM_PROCESSING_AUTOCOMPLETE_ATTRIBUTE_PROCESSING_UTIL_H_
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index 620bc93..eb76e14 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -1273,8 +1273,9 @@
     }
 
     // Compute a section name based on the specified hints and apply the result.
-    if (field->section.SetPrefixFromAutocomplete(parsing_result->section,
-                                                 parsing_result->mode)) {
+    if (field->section.SetPrefixFromAutocomplete(
+            {.section = parsing_result->section,
+             .mode = parsing_result->mode})) {
       has_author_specified_sections_ = true;
     }
     field->SetHtmlType(parsing_result->field_type, parsing_result->mode);
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc
index 6ce0f33..f88a89d 100644
--- a/components/autofill/core/browser/form_structure_unittest.cc
+++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -6590,8 +6590,8 @@
   field.max_length = 10000;
 
   // Billing.
-  field.section.SetPrefixFromAutocomplete("Billing",
-                                          HtmlFieldMode::HTML_MODE_NONE);
+  field.section.SetPrefixFromAutocomplete(
+      {.section = "Billing", .mode = HtmlFieldMode::HTML_MODE_NONE});
 
   field.label = u"Full Name";
   field.name = u"fullName";
@@ -6609,8 +6609,8 @@
   form.fields.push_back(field);
 
   // Shipping.
-  field.section.SetPrefixFromAutocomplete("Shipping",
-                                          HtmlFieldMode::HTML_MODE_NONE);
+  field.section.SetPrefixFromAutocomplete(
+      {.section = "Shipping", .mode = HtmlFieldMode::HTML_MODE_NONE});
 
   field.label = u"Full Name";
   field.name = u"fullName";
@@ -6678,8 +6678,8 @@
   field.max_length = 10000;
 
   // Shipping.
-  field.section.SetPrefixFromAutocomplete("Shipping",
-                                          HtmlFieldMode::HTML_MODE_NONE);
+  field.section.SetPrefixFromAutocomplete(
+      {.section = "Shipping", .mode = HtmlFieldMode::HTML_MODE_NONE});
   field.label = u"Full Name";
   field.name = u"fullName";
   field.unique_renderer_id = MakeFieldRendererId();
@@ -6701,8 +6701,8 @@
   form.fields.push_back(field);
 
   // Billing.
-  field.section.SetPrefixFromAutocomplete("Billing",
-                                          HtmlFieldMode::HTML_MODE_NONE);
+  field.section.SetPrefixFromAutocomplete(
+      {.section = "Billing", .mode = HtmlFieldMode::HTML_MODE_NONE});
   field.label = u"Full Name";
   field.name = u"fullName";
   field.unique_renderer_id = MakeFieldRendererId();
@@ -6729,8 +6729,8 @@
   form.fields.push_back(field);
 
   // Work address (not realistic).
-  field.section.SetPrefixFromAutocomplete("Work",
-                                          HtmlFieldMode::HTML_MODE_NONE);
+  field.section.SetPrefixFromAutocomplete(
+      {.section = "Work", .mode = HtmlFieldMode::HTML_MODE_NONE});
   field.label = u"Full Name";
   field.name = u"fullName";
   field.unique_renderer_id = MakeFieldRendererId();
@@ -7131,8 +7131,8 @@
   field.max_length = 10000;
 
   // Shipping.
-  field.section.SetPrefixFromAutocomplete("shipping",
-                                          HtmlFieldMode::HTML_MODE_NONE);
+  field.section.SetPrefixFromAutocomplete(
+      {.section = "shipping", .mode = HtmlFieldMode::HTML_MODE_NONE});
 
   field.label = u"Full Name";
   field.name = u"fullName";
@@ -7155,8 +7155,8 @@
   form.fields.push_back(field);
 
   // Billing.
-  field.section.SetPrefixFromAutocomplete("billing",
-                                          HtmlFieldMode::HTML_MODE_NONE);
+  field.section.SetPrefixFromAutocomplete(
+      {.section = "billing", .mode = HtmlFieldMode::HTML_MODE_NONE});
 
   field.label = u"Country";
   field.name = u"country2";
@@ -7206,8 +7206,8 @@
   form.fields.push_back(field);
 
   // Billing-2.
-  field.section.SetPrefixFromAutocomplete("billing-2",
-                                          HtmlFieldMode::HTML_MODE_NONE);
+  field.section.SetPrefixFromAutocomplete(
+      {.section = "billing-2", .mode = HtmlFieldMode::HTML_MODE_NONE});
 
   field.label = u"Country";
   field.name = u"country";
@@ -7444,8 +7444,8 @@
   field.form_control_type = "text";
   field.max_length = 10000;
 
-  field.section.SetPrefixFromAutocomplete("billing",
-                                          HtmlFieldMode::HTML_MODE_NONE);
+  field.section.SetPrefixFromAutocomplete(
+      {.section = "billing", .mode = HtmlFieldMode::HTML_MODE_NONE});
 
   field.label = u"Country";
   field.name = u"country";
@@ -7514,8 +7514,8 @@
   field.form_control_type = "text";
   field.max_length = 10000;
 
-  field.section.SetPrefixFromAutocomplete("billing",
-                                          HtmlFieldMode::HTML_MODE_NONE);
+  field.section.SetPrefixFromAutocomplete(
+      {.section = "billing", .mode = HtmlFieldMode::HTML_MODE_NONE});
 
   field.label = u"Country";
   field.name = u"country";
diff --git a/components/autofill/core/browser/personal_data_manager.h b/components/autofill/core/browser/personal_data_manager.h
index 27295af..7d6f424 100644
--- a/components/autofill/core/browser/personal_data_manager.h
+++ b/components/autofill/core/browser/personal_data_manager.h
@@ -370,6 +370,7 @@
     variations_country_code_ = country_code;
   }
 
+#if BUILDFLAG(IS_IOS)
   // Returns the raw pointer to PersonalDataManagerCleaner used for testing
   // purposes.
   PersonalDataManagerCleaner* personal_data_manager_cleaner_for_testing()
@@ -377,7 +378,8 @@
     DCHECK(personal_data_manager_cleaner_);
     return personal_data_manager_cleaner_.get();
   }
-#endif
+#endif  // IOS
+#endif  // UNIT_TEST
 
   // Returns our best guess for the country a user is likely to use when
   // inputting a new address. The value is calculated once and cached, so it
@@ -510,32 +512,6 @@
   FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest, GetCreditCardByServerId);
   FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
                            AddAndGetCreditCardArtImage);
-  FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
-                           DedupeProfiles_ProfilesToDelete);
-  FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
-                           DedupeProfiles_GuidsMergeMap);
-  FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
-                           UpdateCardsBillingAddressReference);
-  FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
-                           ApplyDedupingRoutine_CardsBillingAddressIdUpdated);
-  FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
-                           ApplyDedupingRoutine_MergedProfileValues);
-  FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
-                           ApplyDedupingRoutine_VerifiedProfileFirst);
-  FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
-                           ApplyDedupingRoutine_VerifiedProfileLast);
-  FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
-                           ApplyDedupingRoutine_MultipleVerifiedProfiles);
-  FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
-                           ApplyDedupingRoutine_FeatureDisabled);
-  FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
-                           ApplyDedupingRoutine_NopIfZeroProfiles);
-  FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
-                           ApplyDedupingRoutine_NopIfOneProfile);
-  FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
-                           ApplyDedupingRoutine_OncePerVersion);
-  FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
-                           ApplyDedupingRoutine_MultipleDedupes);
   FRIEND_TEST_ALL_PREFIXES(
       PersonalDataManagerTest,
       ConvertWalletAddressesAndUpdateWalletCards_NewProfile);
@@ -555,9 +531,6 @@
                            DoNotConvertWalletAddressesInEphemeralStorage);
   FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
                            DeleteDisusedCreditCards_DoNothingWhenDisabled);
-  FRIEND_TEST_ALL_PREFIXES(
-      PersonalDataManagerTest,
-      DeleteDisusedCreditCards_OnlyDeleteExpiredDisusedLocalCards);
   FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
                            GetProfileSuggestions_ProfileAutofillDisabled);
   FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest,
@@ -572,6 +545,8 @@
       PersonalDataManagerTest,
       GetCreditCardsToSuggest_NoCreditCardsAddedIfDisabled);
   FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerTest, LogStoredCreditCardMetrics);
+  FRIEND_TEST_ALL_PREFIXES(PersonalDataManagerCleanerTest,
+                           UpdateCardsBillingAddressReference);
 
   friend class autofill::AutofillInteractiveTest;
   friend class autofill::PersonalDataManagerCleaner;
diff --git a/components/autofill/core/browser/personal_data_manager_cleaner_unittest.cc b/components/autofill/core/browser/personal_data_manager_cleaner_unittest.cc
new file mode 100644
index 0000000..4ad0a09
--- /dev/null
+++ b/components/autofill/core/browser/personal_data_manager_cleaner_unittest.cc
@@ -0,0 +1,1290 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/personal_data_manager_cleaner.h"
+
+#include "base/guid.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/test/task_environment.h"
+#include "components/autofill/core/browser/autofill_test_utils.h"
+#include "components/autofill/core/browser/personal_data_manager.h"
+#include "components/autofill/core/browser/personal_data_manager_test_base.h"
+#include "components/autofill/core/common/autofill_clock.h"
+#include "components/autofill/core/common/autofill_constants.h"
+#include "components/autofill/core/common/autofill_features.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::Matcher;
+using ::testing::Truly;
+
+namespace autofill {
+
+namespace {
+
+const base::Time kArbitraryTime = base::Time::FromDoubleT(25);
+const base::Time kSomeLaterTime = base::Time::FromDoubleT(1000);
+const base::Time kMuchLaterTime = base::Time::FromDoubleT(5000);
+
+ACTION_P(QuitMessageLoop, loop) {
+  loop->Quit();
+}
+
+template <typename T>
+auto HasSameElements(const std::vector<T*>& expectations) {
+  std::vector<Matcher<T*>> matchers;
+  for (const auto& e : expectations)
+    matchers.push_back(Truly([e](T* a) { return a->Compare(*e) == 0; }));
+  return UnorderedElementsAreArray(matchers);
+}
+
+}  // anonymous namespace
+
+class PersonalDataManagerCleanerTest : public PersonalDataManagerTestBase,
+                                       public testing::Test {
+ public:
+  PersonalDataManagerCleanerTest() = default;
+  ~PersonalDataManagerCleanerTest() override = default;
+
+  void SetUp() override {
+    SetUpTest();
+    personal_data_ = std::make_unique<PersonalDataManager>("EN", "US");
+    ResetPersonalDataManager(/*is_incognito=*/false,
+                             /*use_sync_transport_mode=*/false,
+                             personal_data_.get());
+    personal_data_manager_cleaner_ =
+        std::make_unique<PersonalDataManagerCleaner>(personal_data_.get(),
+                                                     nullptr, prefs_.get());
+  }
+
+  void TearDown() override {
+    if (personal_data_)
+      personal_data_->Shutdown();
+    personal_data_.reset();
+    TearDownTest();
+  }
+
+ protected:
+  // Verifies that the web database has been updated and the notification sent.
+  void WaitForOnPersonalDataChanged(
+      absl::optional<AutofillProfile> profile = absl::nullopt) {
+    base::RunLoop run_loop;
+    EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
+        .WillOnce(QuitMessageLoop(&run_loop));
+    EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+        .Times(testing::AnyNumber());
+    if (profile)
+      personal_data_->AddProfile(profile.value());
+    run_loop.Run();
+  }
+
+  void AddProfileToPersonalDataManager(const AutofillProfile& profile) {
+    WaitForOnPersonalDataChanged(profile);
+  }
+
+  void SetServerCards(const std::vector<CreditCard>& server_cards) {
+    test::SetServerCreditCards(personal_data_->IsSyncFeatureEnabled()
+                                   ? profile_autofill_table_.get()
+                                   : account_autofill_table_.get(),
+                               server_cards);
+  }
+
+  std::unique_ptr<PersonalDataManager> personal_data_;
+  std::unique_ptr<PersonalDataManagerCleaner> personal_data_manager_cleaner_;
+};
+
+// Tests that DedupeProfiles sets the correct profile guids to
+// delete after merging similar profiles.
+TEST_F(PersonalDataManagerCleanerTest, DedupeProfiles_ProfilesToDelete) {
+  // Create the profile for which to find duplicates. It has the highest
+  // ranking score.
+  AutofillProfile* profile1 =
+      new AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(profile1, "Homer", "Jay", "Simpson",
+                       "homer.simpson@abc.com", "", "742. Evergreen Terrace",
+                       "", "Springfield", "IL", "91601", "US", "12345678910");
+  profile1->set_use_count(9);
+
+  // Create a different profile that should not be deduped (different address).
+  AutofillProfile* profile2 =
+      new AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(profile2, "Homer", "Jay", "Simpson",
+                       "homer.simpson@abc.com", "Fox", "1234 Other Street", "",
+                       "Springfield", "IL", "91601", "US", "12345678910");
+  profile2->set_use_count(7);
+
+  // Create a profile similar to profile1 which should be deduped.
+  AutofillProfile* profile3 =
+      new AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(profile3, "Homer", "Jay", "Simpson",
+                       "homer.simpson@abc.com", "", "742 Evergreen Terrace", "",
+                       "Springfield", "IL", "91601", "US", "12345678910");
+  profile3->set_use_count(5);
+
+  // Create another different profile that should not be deduped (different
+  // name).
+  AutofillProfile* profile4 =
+      new AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(profile4, "Marjorie", "Jacqueline", "Simpson",
+                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace",
+                       "", "Springfield", "IL", "91601", "US", "12345678910");
+  profile4->set_use_count(3);
+
+  // Create another profile similar to profile1. Since that one has the lowest
+  // ranking score, the result of the merge should be in this profile at the end
+  // of the test.
+  AutofillProfile* profile5 =
+      new AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(profile5, "Homer", "Jay", "Simpson",
+                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
+                       "", "Springfield", "IL", "91601", "US", "12345678910");
+  profile5->set_use_count(1);
+
+  // Add the profiles.
+  std::vector<std::unique_ptr<AutofillProfile>> existing_profiles;
+  existing_profiles.push_back(std::unique_ptr<AutofillProfile>(profile1));
+  existing_profiles.push_back(std::unique_ptr<AutofillProfile>(profile2));
+  existing_profiles.push_back(std::unique_ptr<AutofillProfile>(profile3));
+  existing_profiles.push_back(std::unique_ptr<AutofillProfile>(profile4));
+  existing_profiles.push_back(std::unique_ptr<AutofillProfile>(profile5));
+
+  base::HistogramTester histogram_tester;
+  std::unordered_map<std::string, std::string> guids_merge_map;
+  std::unordered_set<std::string> profiles_to_delete;
+  personal_data_manager_cleaner_->DedupeProfilesForTesting(
+      &existing_profiles, &profiles_to_delete, &guids_merge_map);
+  // 5 profiles were considered for dedupe.
+  histogram_tester.ExpectUniqueSample(
+      "Autofill.NumberOfProfilesConsideredForDedupe", 5, 1);
+  // 2 profiles were removed (profiles 1 and 3).
+  histogram_tester.ExpectUniqueSample(
+      "Autofill.NumberOfProfilesRemovedDuringDedupe", 2, 1);
+
+  // Profile1 should be deleted because it was sent as the profile to merge and
+  // thus was merged into profile3 and then into profile5.
+  EXPECT_TRUE(profiles_to_delete.count(profile1->guid()));
+
+  // Profile3 should be deleted because profile1 was merged into it and the
+  // resulting profile was then merged into profile5.
+  EXPECT_TRUE(profiles_to_delete.count(profile3->guid()));
+
+  // Only these two profiles should be deleted.
+  EXPECT_EQ(2U, profiles_to_delete.size());
+
+  // All profiles should still be present in |existing_profiles|.
+  EXPECT_EQ(5U, existing_profiles.size());
+}
+
+// Tests that DedupeProfiles sets the correct merge mapping for billing address
+// id references.
+TEST_F(PersonalDataManagerCleanerTest, DedupeProfiles_GuidsMergeMap) {
+  // Create the profile for which to find duplicates. It has the highest
+  // ranking score.
+  AutofillProfile* profile1 =
+      new AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(profile1, "Homer", "Jay", "Simpson",
+                       "homer.simpson@abc.com", "", "742. Evergreen Terrace",
+                       "", "Springfield", "IL", "91601", "US", "12345678910");
+  profile1->set_use_count(9);
+
+  // Create a different profile that should not be deduped (different address).
+  AutofillProfile* profile2 =
+      new AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(profile2, "Homer", "Jay", "Simpson",
+                       "homer.simpson@abc.com", "Fox", "1234 Other Street", "",
+                       "Springfield", "IL", "91601", "US", "12345678910");
+  profile2->set_use_count(7);
+
+  // Create a profile similar to profile1 which should be deduped.
+  AutofillProfile* profile3 =
+      new AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(profile3, "Homer", "Jay", "Simpson",
+                       "homer.simpson@abc.com", "", "742 Evergreen Terrace", "",
+                       "Springfield", "IL", "91601", "US", "12345678910");
+  profile3->set_use_count(5);
+
+  // Create another different profile that should not be deduped (different
+  // name).
+  AutofillProfile* profile4 =
+      new AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(profile4, "Marjorie", "Jacqueline", "Simpson",
+                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace",
+                       "", "Springfield", "IL", "91601", "US", "12345678910");
+  profile4->set_use_count(3);
+
+  // Create another profile similar to profile1. Since that one has the lowest
+  // ranking score, the result of the merge should be in this profile at the end
+  // of the test.
+  AutofillProfile* profile5 =
+      new AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(profile5, "Homer", "Jay", "Simpson",
+                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
+                       "", "Springfield", "IL", "91601", "US", "12345678910");
+  profile5->set_use_count(1);
+
+  // Add the profiles.
+  std::vector<std::unique_ptr<AutofillProfile>> existing_profiles;
+  existing_profiles.push_back(std::unique_ptr<AutofillProfile>(profile1));
+  existing_profiles.push_back(std::unique_ptr<AutofillProfile>(profile2));
+  existing_profiles.push_back(std::unique_ptr<AutofillProfile>(profile3));
+  existing_profiles.push_back(std::unique_ptr<AutofillProfile>(profile4));
+  existing_profiles.push_back(std::unique_ptr<AutofillProfile>(profile5));
+
+  std::unordered_map<std::string, std::string> guids_merge_map;
+  std::unordered_set<std::string> profiles_to_delete;
+
+  personal_data_manager_cleaner_->DedupeProfilesForTesting(
+      &existing_profiles, &profiles_to_delete, &guids_merge_map);
+
+  // The two profile merges should be recorded in the map.
+  EXPECT_EQ(2U, guids_merge_map.size());
+
+  // Profile 1 was merged into profile 3.
+  ASSERT_TRUE(guids_merge_map.count(profile1->guid()));
+  EXPECT_TRUE(guids_merge_map.at(profile1->guid()) == profile3->guid());
+
+  // Profile 3 was merged into profile 5.
+  ASSERT_TRUE(guids_merge_map.count(profile3->guid()));
+  EXPECT_TRUE(guids_merge_map.at(profile3->guid()) == profile5->guid());
+}
+
+// Tests that UpdateCardsBillingAddressReference sets the correct billing
+// address id as specified in the map.
+TEST_F(PersonalDataManagerCleanerTest, UpdateCardsBillingAddressReference) {
+  /*  The merges will be as follow:
+
+      A -> B            F (not merged)
+             \
+               -> E
+             /
+      C -> D
+  */
+
+  std::unordered_map<std::string, std::string> guids_merge_map;
+  guids_merge_map.insert(std::pair<std::string, std::string>("A", "B"));
+  guids_merge_map.insert(std::pair<std::string, std::string>("C", "D"));
+  guids_merge_map.insert(std::pair<std::string, std::string>("B", "E"));
+  guids_merge_map.insert(std::pair<std::string, std::string>("D", "E"));
+
+  // Create a credit card without a billing address id
+  CreditCard* credit_card0 =
+      new CreditCard(base::GenerateGUID(), test::kEmptyOrigin);
+
+  // Create cards that use A, D, E and F as their billing address id.
+  CreditCard* credit_card1 =
+      new CreditCard(base::GenerateGUID(), test::kEmptyOrigin);
+  credit_card1->set_billing_address_id("A");
+  CreditCard* credit_card2 =
+      new CreditCard(base::GenerateGUID(), test::kEmptyOrigin);
+  credit_card2->set_billing_address_id("D");
+  CreditCard* credit_card3 =
+      new CreditCard(base::GenerateGUID(), test::kEmptyOrigin);
+  credit_card3->set_billing_address_id("E");
+  CreditCard* credit_card4 =
+      new CreditCard(base::GenerateGUID(), test::kEmptyOrigin);
+  credit_card4->set_billing_address_id("F");
+
+  // Add the credit cards to the database.
+  personal_data_->local_credit_cards_.push_back(
+      std::unique_ptr<CreditCard>(credit_card0));
+  personal_data_->local_credit_cards_.push_back(
+      std::unique_ptr<CreditCard>(credit_card1));
+  personal_data_->server_credit_cards_.push_back(
+      std::unique_ptr<CreditCard>(credit_card2));
+  personal_data_->local_credit_cards_.push_back(
+      std::unique_ptr<CreditCard>(credit_card3));
+  personal_data_->server_credit_cards_.push_back(
+      std::unique_ptr<CreditCard>(credit_card4));
+
+  personal_data_manager_cleaner_->UpdateCardsBillingAddressReferenceForTesting(
+      guids_merge_map);
+
+  // The first card's billing address should now be E.
+  EXPECT_EQ("E", credit_card1->billing_address_id());
+  // The second card's billing address should now be E.
+  EXPECT_EQ("E", credit_card2->billing_address_id());
+  // The third card's billing address should still be E.
+  EXPECT_EQ("E", credit_card3->billing_address_id());
+  // The fourth card's billing address should still be F.
+  EXPECT_EQ("F", credit_card4->billing_address_id());
+}
+
+// Tests that ApplyDedupingRoutine updates the credit cards' billing address id
+// based on the deduped profiles.
+TEST_F(PersonalDataManagerCleanerTest,
+       ApplyDedupingRoutine_CardsBillingAddressIdUpdated) {
+  base::test::ScopedFeatureList feature;
+  feature.InitAndEnableFeature(features::kAutofillEnableProfileDeduplication);
+
+  // A set of 6 profiles will be created. They should merge in this way:
+  //  1 -> 2 -> 3
+  //  4 -> 5
+  //  6
+  // Set their frencency score so that profile 3 has a higher score than 5, and
+  // 5 has a higher score than 6. This will ensure a deterministic order when
+  // verifying results.
+
+  // Create a set of 3 profiles to be merged together.
+  // Create a profile with a higher ranking score.
+  AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile1, "Homer", "J", "Simpson",
+                       "homer.simpson@abc.com", "", "742. Evergreen Terrace",
+                       "", "Springfield", "IL", "91601", "US", "");
+  profile1.set_use_count(12);
+  profile1.set_use_date(AutofillClock::Now() - base::Days(1));
+
+  // Create a profile with a medium ranking score.
+  AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile2, "Homer", "Jay", "Simpson",
+                       "homer.simpson@abc.com", "", "742 Evergreen Terrace", "",
+                       "Springfield", "IL", "91601", "", "12345678910");
+  profile2.set_use_count(5);
+  profile2.set_use_date(AutofillClock::Now() - base::Days(3));
+
+  // Create a profile with a lower ranking score.
+  AutofillProfile profile3(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile3, "Homer", "J", "Simpson",
+                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
+                       "", "Springfield", "IL", "91601", "", "");
+  profile3.set_use_count(3);
+  profile3.set_use_date(AutofillClock::Now() - base::Days(5));
+
+  // Create a set of two profiles to be merged together.
+  // Create a profile with a higher ranking score.
+  AutofillProfile profile4(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile4, "Marge", "B", "Simpson",
+                       "marge.simpson@abc.com", "", "742. Evergreen Terrace",
+                       "", "Springfield", "IL", "91601", "US", "");
+  profile4.set_use_count(11);
+  profile4.set_use_date(AutofillClock::Now() - base::Days(1));
+
+  // Create a profile with a lower ranking score.
+  AutofillProfile profile5(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile5, "Marge", "B", "Simpson",
+                       "marge.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
+                       "", "Springfield", "IL", "91601", "", "");
+  profile5.set_use_count(5);
+  profile5.set_use_date(AutofillClock::Now() - base::Days(3));
+
+  // Create a unique profile.
+  AutofillProfile profile6(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile6, "Bart", "J", "Simpson",
+                       "bart.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
+                       "", "Springfield", "IL", "91601", "", "");
+  profile6.set_use_count(10);
+  profile6.set_use_date(AutofillClock::Now() - base::Days(1));
+
+  // Add three credit cards. Give them a ranking score so that they are
+  // suggested in order (1, 2, 3). This will ensure a deterministic order for
+  // verifying results.
+  CreditCard credit_card1(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetCreditCardInfo(&credit_card1, "Clyde Barrow",
+                          "378282246310005" /* American Express */, "04",
+                          "2999", "1");
+  credit_card1.set_use_count(10);
+
+  CreditCard credit_card2(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetCreditCardInfo(&credit_card2, "John Dillinger",
+                          "4234567890123456" /* Visa */, "01", "2999", "1");
+  credit_card2.set_use_count(5);
+
+  CreditCard credit_card3(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetCreditCardInfo(&credit_card3, "Bonnie Parker",
+                          "5105105105105100" /* Mastercard */, "12", "2999",
+                          "1");
+  credit_card3.set_use_count(1);
+
+  // Associate the first card with profile1.
+  credit_card1.set_billing_address_id(profile1.guid());
+  // Associate the second card with profile4.
+  credit_card2.set_billing_address_id(profile4.guid());
+  // Associate the third card with profile6.
+  credit_card3.set_billing_address_id(profile6.guid());
+
+  AddProfileToPersonalDataManager(profile1);
+  AddProfileToPersonalDataManager(profile2);
+  AddProfileToPersonalDataManager(profile3);
+  AddProfileToPersonalDataManager(profile4);
+  AddProfileToPersonalDataManager(profile5);
+  AddProfileToPersonalDataManager(profile6);
+  personal_data_->AddCreditCard(credit_card1);
+  personal_data_->AddCreditCard(credit_card2);
+  personal_data_->AddCreditCard(credit_card3);
+
+  WaitForOnPersonalDataChanged();
+
+  // Make sure the 6 profiles and 3 credit cards were saved.
+  EXPECT_EQ(6U, personal_data_->GetProfiles().size());
+  EXPECT_EQ(3U, personal_data_->GetCreditCards().size());
+
+  EXPECT_TRUE(personal_data_manager_cleaner_->ApplyDedupingRoutineForTesting());
+  WaitForOnPersonalDataChanged();
+
+  // Get the profiles and cards sorted by their ranking score to have a
+  // deterministic order.
+  std::vector<AutofillProfile*> profiles =
+      personal_data_->GetProfilesToSuggest();
+  std::vector<CreditCard*> credit_cards =
+      personal_data_->GetCreditCardsToSuggest(/*include_server_cards=*/true);
+
+  // |profile1| should have been merged into |profile2| which should then have
+  // been merged into |profile3|. |profile4| should have been merged into
+  // |profile5| and |profile6| should not have merged. Therefore there should be
+  // 3 profile left.
+  ASSERT_EQ(3U, profiles.size());
+
+  // Make sure the remaining profiles are the expected ones.
+  EXPECT_EQ(profile3.guid(), profiles[0]->guid());
+  EXPECT_EQ(profile5.guid(), profiles[1]->guid());
+  EXPECT_EQ(profile6.guid(), profiles[2]->guid());
+
+  // |credit_card1|'s billing address should now be profile 3.
+  EXPECT_EQ(profile3.guid(), credit_cards[0]->billing_address_id());
+
+  // |credit_card2|'s billing address should now be profile 5.
+  EXPECT_EQ(profile5.guid(), credit_cards[1]->billing_address_id());
+
+  // |credit_card3|'s billing address should still be profile 6.
+  EXPECT_EQ(profile6.guid(), credit_cards[2]->billing_address_id());
+}
+
+// Tests that ApplyDedupingRoutine merges the profile values correctly, i.e.
+// never lose information and keep the syntax of the profile with the higher
+// ranking score.
+TEST_F(PersonalDataManagerCleanerTest,
+       ApplyDedupingRoutine_MergedProfileValues) {
+  base::test::ScopedFeatureList feature;
+  feature.InitAndEnableFeature(features::kAutofillEnableProfileDeduplication);
+
+  // Create a profile with a higher ranking score.
+  AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile1, "Homer", "J", "Simpson",
+                       "homer.simpson@abc.com", "", "742. Evergreen Terrace",
+                       "", "Springfield", "IL", "91601", "US", "");
+  profile1.set_use_count(10);
+  profile1.set_use_date(AutofillClock::Now() - base::Days(1));
+
+  // Create a profile with a medium ranking score.
+  AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile2, "Homer", "Jay", "Simpson",
+                       "homer.simpson@abc.com", "", "742 Evergreen Terrace", "",
+                       "Springfield", "IL", "91601", "", "12345678910");
+  profile2.set_use_count(5);
+  profile2.set_use_date(AutofillClock::Now() - base::Days(3));
+
+  // Create a profile with a lower ranking score.
+  AutofillProfile profile3(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile3, "Homer", "J", "Simpson",
+                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
+                       "", "Springfield", "IL", "91601", "", "");
+  profile3.set_use_count(3);
+  profile3.set_use_date(AutofillClock::Now() - base::Days(5));
+
+  AddProfileToPersonalDataManager(profile1);
+  AddProfileToPersonalDataManager(profile2);
+  AddProfileToPersonalDataManager(profile3);
+
+  // Make sure the 3 profiles were saved;
+  EXPECT_EQ(3U, personal_data_->GetProfiles().size());
+
+  base::HistogramTester histogram_tester;
+
+  EXPECT_TRUE(personal_data_manager_cleaner_->ApplyDedupingRoutineForTesting());
+  WaitForOnPersonalDataChanged();
+
+  std::vector<AutofillProfile*> profiles = personal_data_->GetProfiles();
+
+  // |profile1| should have been merged into |profile2| which should then have
+  // been merged into |profile3|. Therefore there should only be 1 saved
+  // profile.
+  ASSERT_EQ(1U, profiles.size());
+  // 3 profiles were considered for dedupe.
+  histogram_tester.ExpectUniqueSample(
+      "Autofill.NumberOfProfilesConsideredForDedupe", 3, 1);
+  // 2 profiles were removed (profiles 1 and 2).
+  histogram_tester.ExpectUniqueSample(
+      "Autofill.NumberOfProfilesRemovedDuringDedupe", 2, 1);
+
+  // Since profiles with higher ranking scores are merged into profiles with
+  // lower ranking scores, the result of the merge should be contained in
+  // profile3 since it had a lower ranking score compared to profile1.
+  EXPECT_EQ(profile3.guid(), profiles[0]->guid());
+  // The address syntax that results from the merge should be the one from the
+  // imported profile (highest ranking).
+  EXPECT_EQ(u"742. Evergreen Terrace",
+            profiles[0]->GetRawInfo(ADDRESS_HOME_LINE1));
+  // The middle name should be full, even if the profile with the higher
+  // ranking only had an initial (no loss of information).
+  EXPECT_EQ(u"Jay", profiles[0]->GetRawInfo(NAME_MIDDLE));
+  // The specified phone number from profile1 should be kept (no loss of
+  // information).
+  EXPECT_EQ(u"12345678910", profiles[0]->GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
+  // The specified company name from profile2 should be kept (no loss of
+  // information).
+  EXPECT_EQ(u"Fox", profiles[0]->GetRawInfo(COMPANY_NAME));
+  // The specified country from the imported profile should be kept (no loss of
+  // information).
+  EXPECT_EQ(u"US", profiles[0]->GetRawInfo(ADDRESS_HOME_COUNTRY));
+  // The use count that results from the merge should be the max of all the
+  // profiles use counts.
+  EXPECT_EQ(10U, profiles[0]->use_count());
+  // The use date that results from the merge should be the one from the
+  // profile1 since it was the most recently used profile.
+  EXPECT_LT(profile1.use_date() - base::Seconds(10), profiles[0]->use_date());
+}
+
+// Tests that ApplyDedupingRoutine only keeps the verified profile with its
+// original data when deduping with similar profiles, even if it has a higher
+// ranking score.
+TEST_F(PersonalDataManagerCleanerTest,
+       ApplyDedupingRoutine_VerifiedProfileFirst) {
+  base::test::ScopedFeatureList feature;
+  feature.InitAndEnableFeature(features::kAutofillEnableProfileDeduplication);
+
+  // Create a verified profile with a higher ranking score.
+  AutofillProfile profile1(base::GenerateGUID(), kSettingsOrigin);
+  test::SetProfileInfo(
+      &profile1, "Homer", "Jay", "Simpson", "homer.simpson@abc.com", "",
+      "742 Evergreen Terrace", "", "Springfield", "IL", "91601", "",
+      "12345678910", /*finalize=*/true,
+      /*status=*/structured_address::VerificationStatus::kUserVerified);
+  profile1.set_use_count(7);
+  profile1.set_use_date(kMuchLaterTime);
+
+  // Create a similar non verified profile with a medium ranking score.
+  AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile2, "Homer", "J", "Simpson",
+                       "homer.simpson@abc.com", "", "742. Evergreen Terrace",
+                       "", "Springfield", "IL", "91601", "US", "");
+  profile2.set_use_count(5);
+  profile2.set_use_date(kSomeLaterTime);
+
+  // Create a similar non verified profile with a lower ranking score.
+  AutofillProfile profile3(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile3, "Homer", "J", "Simpson",
+                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
+                       "", "Springfield", "IL", "91601", "", "");
+  profile3.set_use_count(3);
+  profile3.set_use_date(kArbitraryTime);
+
+  AddProfileToPersonalDataManager(profile1);
+  AddProfileToPersonalDataManager(profile2);
+  AddProfileToPersonalDataManager(profile3);
+
+  // Make sure the 3 profiles were saved.
+  EXPECT_EQ(3U, personal_data_->GetProfiles().size());
+
+  base::HistogramTester histogram_tester;
+
+  EXPECT_TRUE(personal_data_manager_cleaner_->ApplyDedupingRoutineForTesting());
+  WaitForOnPersonalDataChanged();
+
+  std::vector<AutofillProfile*> profiles = personal_data_->GetProfiles();
+
+  // |profile2| should have merged with |profile3|. |profile3|
+  // should then have been discarded because it is similar to the verified
+  // |profile1|.
+  ASSERT_EQ(1U, profiles.size());
+  // 3 profiles were considered for dedupe.
+  histogram_tester.ExpectUniqueSample(
+      "Autofill.NumberOfProfilesConsideredForDedupe", 3, 1);
+  // 2 profile were removed (profiles 2 and 3).
+  histogram_tester.ExpectUniqueSample(
+      "Autofill.NumberOfProfilesRemovedDuringDedupe", 2, 1);
+
+  // Although the profile was verified, the structure of the  street address
+  // still evolved with future observations. In this case, the "." was added
+  // from a later observation.
+  profile1.SetRawInfoWithVerificationStatus(
+      ADDRESS_HOME_STREET_NAME, u"Evergreen Terrace",
+      structured_address::VerificationStatus::kParsed);
+  //
+  // Only the verified |profile1| with its original data should have been kept.
+  EXPECT_EQ(profile1.guid(), profiles[0]->guid());
+  EXPECT_TRUE(profile1 == *profiles[0]);
+  EXPECT_EQ(profile1.use_count(), profiles[0]->use_count());
+  EXPECT_EQ(profile1.use_date(), profiles[0]->use_date());
+}
+
+// Tests that ApplyDedupingRoutine only keeps the verified profile with its
+// original data when deduping with similar profiles, even if it has a lower
+// ranking score.
+TEST_F(PersonalDataManagerCleanerTest,
+       ApplyDedupingRoutine_VerifiedProfileLast) {
+  base::test::ScopedFeatureList feature;
+  feature.InitAndEnableFeature(features::kAutofillEnableProfileDeduplication);
+
+  // Create a profile to dedupe with a higher ranking score.
+  AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile1, "Homer", "J", "Simpson",
+                       "homer.simpson@abc.com", "", "742. Evergreen Terrace",
+                       "", "Springfield", "IL", "91601", "US", "");
+  profile1.set_use_count(5);
+  profile1.set_use_date(kMuchLaterTime);
+
+  // Create a similar non verified profile with a medium ranking score.
+  AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile2, "Homer", "J", "Simpson",
+                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
+                       "", "Springfield", "IL", "91601", "", "");
+  profile2.set_use_count(5);
+  profile2.set_use_date(kSomeLaterTime);
+
+  // Create a similar verified profile with a lower ranking score.
+  AutofillProfile profile3(base::GenerateGUID(), kSettingsOrigin);
+  test::SetProfileInfo(
+      &profile3, "Homer", "Jay", "Simpson", "homer.simpson@abc.com", "",
+      "742 Evergreen Terrace", "", "Springfield", "IL", "91601", "",
+      "12345678910", /*finalize=*/true,
+      /*status=*/structured_address::VerificationStatus::kUserVerified);
+  profile3.set_use_count(3);
+  profile3.set_use_date(kArbitraryTime);
+
+  AddProfileToPersonalDataManager(profile1);
+  AddProfileToPersonalDataManager(profile2);
+  AddProfileToPersonalDataManager(profile3);
+
+  // Make sure the 3 profiles were saved.
+  EXPECT_EQ(3U, personal_data_->GetProfiles().size());
+
+  base::HistogramTester histogram_tester;
+
+  EXPECT_TRUE(personal_data_manager_cleaner_->ApplyDedupingRoutineForTesting());
+  WaitForOnPersonalDataChanged();
+
+  std::vector<AutofillProfile*> profiles = personal_data_->GetProfiles();
+
+  // |profile1| should have merged with |profile2|. |profile2|
+  // should then have been discarded because it is similar to the verified
+  // |profile3|.
+  ASSERT_EQ(1U, profiles.size());
+  // 3 profiles were considered for dedupe.
+  histogram_tester.ExpectUniqueSample(
+      "Autofill.NumberOfProfilesConsideredForDedupe", 3, 1);
+  // 2 profile were removed (profiles 1 and 2).
+  histogram_tester.ExpectUniqueSample(
+      "Autofill.NumberOfProfilesRemovedDuringDedupe", 2, 1);
+
+  // Only the verified |profile3| with it's original data should have been kept.
+  EXPECT_EQ(profile3.guid(), profiles[0]->guid());
+  EXPECT_TRUE(profile3 == *profiles[0]);
+  EXPECT_EQ(profile3.use_count(), profiles[0]->use_count());
+  EXPECT_EQ(profile3.use_date(), profiles[0]->use_date());
+}
+
+// Tests that ApplyDedupingRoutine does not merge unverified data into
+// a verified profile. Also tests that two verified profiles don't get merged.
+TEST_F(PersonalDataManagerCleanerTest,
+       ApplyDedupingRoutine_MultipleVerifiedProfiles) {
+  base::test::ScopedFeatureList feature;
+  feature.InitAndEnableFeature(features::kAutofillEnableProfileDeduplication);
+
+  // Create a profile to dedupe with a higher ranking score.
+  AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile1, "Homer", "J", "Simpson",
+                       "homer.simpson@abc.com", "", "742. Evergreen Terrace",
+                       "", "Springfield", "IL", "91601", "US", "");
+  profile1.set_use_count(5);
+  profile1.set_use_date(kMuchLaterTime);
+
+  // Create a similar verified profile with a medium ranking score.
+  AutofillProfile profile2(base::GenerateGUID(), kSettingsOrigin);
+  test::SetProfileInfo(
+      &profile2, "Homer", "J", "Simpson", "homer.simpson@abc.com", "Fox",
+      "742 Evergreen Terrace.", "", "Springfield", "IL", "91601", "", "",
+      /*finalize=*/true,
+      /*status=*/structured_address::VerificationStatus::kUserVerified);
+
+  profile2.set_use_count(5);
+  profile2.set_use_date(kSomeLaterTime);
+
+  // Create a similar verified profile with a lower ranking score.
+  AutofillProfile profile3(base::GenerateGUID(), kSettingsOrigin);
+  test::SetProfileInfo(
+      &profile3, "Homer", "Jay", "Simpson", "homer.simpson@abc.com", "",
+      "742 Evergreen Terrace", "", "Springfield", "IL", "91601", "",
+      "12345678910", /*finalize=*/true,
+      /*status*/ structured_address::VerificationStatus::kUserVerified);
+  profile3.set_use_count(3);
+  profile3.set_use_date(kArbitraryTime);
+
+  AddProfileToPersonalDataManager(profile1);
+  AddProfileToPersonalDataManager(profile2);
+  AddProfileToPersonalDataManager(profile3);
+
+  // Make sure the 3 profiles were saved.
+  EXPECT_EQ(3U, personal_data_->GetProfiles().size());
+
+  base::HistogramTester histogram_tester;
+
+  EXPECT_TRUE(personal_data_manager_cleaner_->ApplyDedupingRoutineForTesting());
+  WaitForOnPersonalDataChanged();
+
+  // Get the profiles, sorted by ranking to have a deterministic order.
+  std::vector<AutofillProfile*> profiles =
+      personal_data_->GetProfilesToSuggest();
+
+  // Although the profile was verified, the structure of the  street address
+  // still evolved with future observations. In this case, the "." was removed
+  // from a later observation.
+  profile2.SetRawInfoWithVerificationStatus(
+      ADDRESS_HOME_STREET_NAME, u"Evergreen Terrace",
+      structured_address::VerificationStatus::kParsed);
+
+  // |profile1| should have been discarded because the saved profile with the
+  // highest ranking score is verified (|profile2|). Therefore, |profile1|'s
+  // data should not have been merged with |profile2|'s data. Then |profile2|
+  // should have been compared to |profile3| but they should not have merged
+  // because both profiles are verified.
+  ASSERT_EQ(2U, profiles.size());
+  // 3 profiles were considered for dedupe.
+  histogram_tester.ExpectUniqueSample(
+      "Autofill.NumberOfProfilesConsideredForDedupe", 3, 1);
+  // 1 profile was removed (|profile1|).
+  histogram_tester.ExpectUniqueSample(
+      "Autofill.NumberOfProfilesRemovedDuringDedupe", 1, 1);
+
+  EXPECT_EQ(profile2.guid(), profiles[0]->guid());
+  EXPECT_EQ(profile3.guid(), profiles[1]->guid());
+  // The profiles should have kept their original data.
+  EXPECT_TRUE(profile2 == *profiles[0]);
+  EXPECT_TRUE(profile3 == *profiles[1]);
+  EXPECT_EQ(profile2.use_count(), profiles[0]->use_count());
+  EXPECT_EQ(profile3.use_count(), profiles[1]->use_count());
+  EXPECT_EQ(profile2.use_date(), profiles[0]->use_date());
+  EXPECT_EQ(profile3.use_date(), profiles[1]->use_date());
+}
+
+// Tests that ApplyDedupingRoutine works as expected in a realistic scenario.
+// Tests that it merges the diffent set of similar profiles independently and
+// that the resulting profiles have the right values, has no effect on the other
+// profiles and that the data of verified profiles is not modified.
+TEST_F(PersonalDataManagerCleanerTest, ApplyDedupingRoutine_MultipleDedupes) {
+  base::test::ScopedFeatureList feature;
+  feature.InitAndEnableFeature(features::kAutofillEnableProfileDeduplication);
+
+  // Create a Homer home profile with a higher ranking score than other Homer
+  // profiles.
+  AutofillProfile Homer1(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&Homer1, "Homer", "J", "Simpson",
+                       "homer.simpson@abc.com", "", "742. Evergreen Terrace",
+                       "", "Springfield", "IL", "91601", "US", "");
+  Homer1.set_use_count(10);
+  Homer1.set_use_date(AutofillClock::Now() - base::Days(1));
+
+  // Create a Homer home profile with a medium ranking score compared to other
+  // Homer profiles.
+  AutofillProfile Homer2(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&Homer2, "Homer", "Jay", "Simpson",
+                       "homer.simpson@abc.com", "", "742 Evergreen Terrace", "",
+                       "Springfield", "IL", "91601", "", "12345678910");
+  Homer2.set_use_count(5);
+  Homer2.set_use_date(AutofillClock::Now() - base::Days(3));
+
+  // Create a Homer home profile with a lower ranking score than other Homer
+  // profiles.
+  AutofillProfile Homer3(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&Homer3, "Homer", "J", "Simpson",
+                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
+                       "", "Springfield", "IL", "91601", "", "");
+  Homer3.set_use_count(3);
+  Homer3.set_use_date(AutofillClock::Now() - base::Days(5));
+
+  // Create a Homer work profile (different address).
+  AutofillProfile Homer4(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&Homer4, "Homer", "J", "Simpson",
+                       "homer.simpson@abc.com", "Fox", "12 Nuclear Plant.", "",
+                       "Springfield", "IL", "91601", "US", "9876543");
+  Homer4.set_use_count(3);
+  Homer4.set_use_date(AutofillClock::Now() - base::Days(5));
+
+  // Create a Marge profile with a lower ranking score that other Marge
+  // profiles.
+  AutofillProfile Marge1(base::GenerateGUID(), kSettingsOrigin);
+  test::SetProfileInfo(&Marge1, "Marjorie", "J", "Simpson",
+                       "marge.simpson@abc.com", "", "742 Evergreen Terrace", "",
+                       "Springfield", "IL", "91601", "", "12345678910");
+  Marge1.set_use_count(4);
+  Marge1.set_use_date(AutofillClock::Now() - base::Days(3));
+
+  // Create a verified Marge home profile with a lower ranking score that the
+  // other Marge profile.
+  AutofillProfile Marge2(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&Marge2, "Marjorie", "Jacqueline", "Simpson",
+                       "marge.simpson@abc.com", "", "742 Evergreen Terrace", "",
+                       "Springfield", "IL", "91601", "", "12345678910");
+  Marge2.set_use_count(2);
+  Marge2.set_use_date(AutofillClock::Now() - base::Days(3));
+
+  // Create a Barney profile (guest user).
+  AutofillProfile Barney(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&Barney, "Barney", "", "Gumble", "barney.gumble@abc.com",
+                       "ABC", "123 Other Street", "", "Springfield", "IL",
+                       "91601", "", "");
+  Barney.set_use_count(1);
+  Barney.set_use_date(AutofillClock::Now() - base::Days(180));
+  Barney.FinalizeAfterImport();
+
+  AddProfileToPersonalDataManager(Homer1);
+  AddProfileToPersonalDataManager(Homer2);
+  AddProfileToPersonalDataManager(Homer3);
+  AddProfileToPersonalDataManager(Homer4);
+  AddProfileToPersonalDataManager(Marge1);
+  AddProfileToPersonalDataManager(Marge2);
+  AddProfileToPersonalDataManager(Barney);
+
+  // Make sure the 7 profiles were saved;
+  EXPECT_EQ(7U, personal_data_->GetProfiles().size());
+
+  base::HistogramTester histogram_tester;
+
+  // |Homer1| should get merged into |Homer2| which should then be merged into
+  // |Homer3|. |Marge2| should be discarded in favor of |Marge1| which is
+  // verified. |Homer4| and |Barney| should not be deduped at all.
+  EXPECT_TRUE(personal_data_manager_cleaner_->ApplyDedupingRoutineForTesting());
+  WaitForOnPersonalDataChanged();
+
+  // Get the profiles, sorted by ranking score to have a deterministic order.
+  std::vector<AutofillProfile*> profiles =
+      personal_data_->GetProfilesToSuggest();
+
+  // The 2 duplicates Homer home profiles with the higher ranking score and the
+  // unverified Marge profile should have been deduped.
+  ASSERT_EQ(4U, profiles.size());
+  // 7 profiles were considered for dedupe.
+  histogram_tester.ExpectUniqueSample(
+      "Autofill.NumberOfProfilesConsideredForDedupe", 7, 1);
+  // 3 profile were removed (|Homer1|, |Homer2| and |Marge2|).
+  histogram_tester.ExpectUniqueSample(
+      "Autofill.NumberOfProfilesRemovedDuringDedupe", 3, 1);
+
+  // The remaining profiles should be |Homer3|, |Marge1|, |Homer4| and |Barney|
+  // in this order of ranking score.
+  EXPECT_EQ(Homer3.guid(), profiles[0]->guid());
+  EXPECT_EQ(Marge1.guid(), profiles[1]->guid());
+  EXPECT_EQ(Homer4.guid(), profiles[2]->guid());
+  EXPECT_EQ(Barney.guid(), profiles[3]->guid());
+
+  // |Homer3|'s data:
+  // The address should be saved with the syntax of |Homer1| since it has the
+  // highest ranking score.
+  EXPECT_EQ(u"742. Evergreen Terrace",
+            profiles[0]->GetRawInfo(ADDRESS_HOME_LINE1));
+  // The middle name should be the full version found in |Homer2|,
+  EXPECT_EQ(u"Jay", profiles[0]->GetRawInfo(NAME_MIDDLE));
+  // The phone number from |Homer2| should be kept (no loss of information).
+  EXPECT_EQ(u"12345678910", profiles[0]->GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
+  // The company name from |Homer3| should be kept (no loss of information).
+  EXPECT_EQ(u"Fox", profiles[0]->GetRawInfo(COMPANY_NAME));
+  // The country from |Homer1| profile should be kept (no loss of information).
+  EXPECT_EQ(u"US", profiles[0]->GetRawInfo(ADDRESS_HOME_COUNTRY));
+  // The use count that results from the merge should be the max of Homer 1, 2
+  // and 3's respective use counts.
+  EXPECT_EQ(10U, profiles[0]->use_count());
+  // The use date that results from the merge should be the one from the
+  // |Homer1| since it was the most recently used profile.
+  EXPECT_LT(Homer1.use_date() - base::Seconds(5), profiles[0]->use_date());
+  EXPECT_GT(Homer1.use_date() + base::Seconds(5), profiles[0]->use_date());
+
+  // The other profiles should not have been modified.
+  EXPECT_TRUE(Marge1 == *profiles[1]);
+  EXPECT_TRUE(Homer4 == *profiles[2]);
+  EXPECT_TRUE(Barney == *profiles[3]);
+}
+
+TEST_F(PersonalDataManagerCleanerTest, ApplyDedupingRoutine_NopIfZeroProfiles) {
+  base::test::ScopedFeatureList feature;
+  feature.InitAndEnableFeature(features::kAutofillEnableProfileDeduplication);
+  EXPECT_TRUE(personal_data_->GetProfiles().empty());
+  EXPECT_FALSE(
+      personal_data_manager_cleaner_->ApplyDedupingRoutineForTesting());
+}
+
+TEST_F(PersonalDataManagerCleanerTest, ApplyDedupingRoutine_NopIfOneProfile) {
+  base::test::ScopedFeatureList feature;
+  feature.InitAndEnableFeature(features::kAutofillEnableProfileDeduplication);
+
+  // Create a profile to dedupe.
+  AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile, "Homer", "J", "Simpson",
+                       "homer.simpson@abc.com", "", "742. Evergreen Terrace",
+                       "", "Springfield", "IL", "91601", "US", "");
+
+  AddProfileToPersonalDataManager(profile);
+
+  EXPECT_EQ(1U, personal_data_->GetProfiles().size());
+  EXPECT_FALSE(
+      personal_data_manager_cleaner_->ApplyDedupingRoutineForTesting());
+}
+
+// Tests that ApplyDedupingRoutine is not run a second time on the same major
+// version.
+TEST_F(PersonalDataManagerCleanerTest, ApplyDedupingRoutine_OncePerVersion) {
+  base::test::ScopedFeatureList feature;
+  feature.InitAndEnableFeature(features::kAutofillEnableProfileDeduplication);
+
+  // Create a profile to dedupe.
+  AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile1, "Homer", "J", "Simpson",
+                       "homer.simpson@abc.com", "", "742. Evergreen Terrace",
+                       "", "Springfield", "IL", "91601", "US", "");
+
+  // Create a similar profile.
+  AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile2, "Homer", "J", "Simpson",
+                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
+                       "", "Springfield", "IL", "91601", "", "");
+
+  AddProfileToPersonalDataManager(profile1);
+  AddProfileToPersonalDataManager(profile2);
+
+  EXPECT_EQ(2U, personal_data_->GetProfiles().size());
+
+  // The deduping routine should be run a first time.
+  EXPECT_TRUE(personal_data_manager_cleaner_->ApplyDedupingRoutineForTesting());
+  WaitForOnPersonalDataChanged();
+
+  std::vector<AutofillProfile*> profiles = personal_data_->GetProfiles();
+
+  // The profiles should have been deduped
+  EXPECT_EQ(1U, profiles.size());
+
+  // Add another duplicate profile.
+  AutofillProfile profile3(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile3, "Homer", "J", "Simpson",
+                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
+                       "", "Springfield", "IL", "91601", "", "");
+
+  AddProfileToPersonalDataManager(profile3);
+
+  // Make sure |profile3| was saved.
+  EXPECT_EQ(2U, personal_data_->GetProfiles().size());
+
+  // The deduping routine should not be run.
+  EXPECT_FALSE(
+      personal_data_manager_cleaner_->ApplyDedupingRoutineForTesting());
+
+  // The two duplicate profiles should still be present.
+  EXPECT_EQ(2U, personal_data_->GetProfiles().size());
+}
+
+// Tests that settings-inaccessible profile values are removed from every stored
+// profile on startup.
+TEST_F(PersonalDataManagerCleanerTest,
+       RemoveInaccessibleProfileValuesOnStartup) {
+  base::test::ScopedFeatureList feature;
+  feature.InitAndEnableFeatureWithParameters(
+      features::kAutofillRemoveInaccessibleProfileValues,
+      {{features::kAutofillRemoveInaccessibleProfileValuesOnStartup.name,
+        "true"}});
+
+  // Add a German and a US profile.
+  AutofillProfile profile0(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile0, "Marion", "Mitchell", "Morrison",
+                       "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5",
+                       "Hollywood", "CA", "91601", "DE", "12345678910");
+  AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile1, "Josephine", "Alicia", "Saenz",
+                       "joewayne@me.xyz", "Fox", "903 Apple Ct.", nullptr,
+                       "Orlando", "FL", "32801", "US", "19482937549");
+  AddProfileToPersonalDataManager(profile0);
+  AddProfileToPersonalDataManager(profile1);
+
+  personal_data_manager_cleaner_->RemoveInaccessibleProfileValuesForTesting();
+  WaitForOnPersonalDataChanged();
+
+  // profile0 should have it's state removed, while the US profile should remain
+  // unchanged.
+  profile0.SetRawInfo(ADDRESS_HOME_STATE, u"");
+  std::vector<AutofillProfile*> expected_profiles = {&profile0, &profile1};
+  EXPECT_THAT(personal_data_->GetProfiles(),
+              HasSameElements(expected_profiles));
+}
+
+// Tests that DeleteDisusedAddresses only deletes the addresses that are
+// supposed to be deleted.
+TEST_F(PersonalDataManagerCleanerTest,
+       DeleteDisusedAddresses_DeleteDesiredAddressesOnly) {
+  auto now = AutofillClock::Now();
+
+  // Create unverified/disused/not-used-by-valid-credit-card
+  // address(deletable).
+  AutofillProfile profile0(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile0, "Alice", "", "Delete", "", "ACME",
+                       "1234 Evergreen Terrace", "Bld. 6", "Springfield", "IL",
+                       "32801", "US", "15151231234");
+  profile0.set_use_date(now - base::Days(400));
+  AddProfileToPersonalDataManager(profile0);
+
+  // Create unverified/disused/used-by-expired-credit-card address(deletable).
+  AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile1, "Bob", "", "Delete", "", "ACME",
+                       "1234 Evergreen Terrace", "Bld. 7", "Springfield", "IL",
+                       "32801", "US", "15151231234");
+  profile1.set_use_date(now - base::Days(400));
+  CreditCard credit_card0(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetCreditCardInfo(&credit_card0, "Bob",
+                          "5105105105105100" /* Mastercard */, "04", "1999",
+                          "1");
+  credit_card0.set_use_date(now - base::Days(400));
+  credit_card0.set_billing_address_id(profile1.guid());
+  AddProfileToPersonalDataManager(profile1);
+  personal_data_->AddCreditCard(credit_card0);
+  WaitForOnPersonalDataChanged();
+  // Create verified/disused/not-used-by-valid-credit-card address(not
+  // deletable).
+  AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile2, "Charlie", "", "Keep", "", "ACME",
+                       "1234 Evergreen Terrace", "Bld. 8", "Springfield", "IL",
+                       "32801", "US", "15151231234");
+  profile2.set_origin(kSettingsOrigin);
+  profile2.set_use_date(now - base::Days(400));
+  AddProfileToPersonalDataManager(profile2);
+
+  // Create unverified/recently-used/not-used-by-valid-credit-card address(not
+  // deletable).
+  AutofillProfile profile3(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile3, "Dave", "", "Keep", "", "ACME",
+                       "1234 Evergreen Terrace", "Bld. 9", "Springfield", "IL",
+                       "32801", "US", "15151231234");
+  profile3.set_use_date(now - base::Days(4));
+  AddProfileToPersonalDataManager(profile3);
+
+  // Create unverified/disused/used-by-valid-credit-card address(not deletable).
+  AutofillProfile profile4(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile4, "Emma", "", "Keep", "", "ACME",
+                       "1234 Evergreen Terrace", "Bld. 10", "Springfield", "IL",
+                       "32801", "US", "15151231234");
+  profile4.set_use_date(now - base::Days(400));
+  CreditCard credit_card1(CreditCard::MASKED_SERVER_CARD, "c987");
+  test::SetCreditCardInfo(&credit_card1, "Emma", "6543", "01", "2999", "1");
+  credit_card1.SetNetworkForMaskedCard(kVisaCard);
+  credit_card1.set_billing_address_id(profile4.guid());
+  credit_card1.set_use_date(now - base::Days(1));
+  AddProfileToPersonalDataManager(profile4);
+  personal_data_->AddCreditCard(credit_card1);
+
+  WaitForOnPersonalDataChanged();
+
+  EXPECT_EQ(5U, personal_data_->GetProfiles().size());
+  EXPECT_EQ(2U, personal_data_->GetCreditCards().size());
+
+  // DeleteDisusedAddresses should return true.
+  EXPECT_TRUE(
+      personal_data_manager_cleaner_->DeleteDisusedAddressesForTesting());
+  WaitForOnPersonalDataChanged();
+
+  EXPECT_EQ(3U, personal_data_->GetProfiles().size());
+  EXPECT_EQ(2U, personal_data_->GetCreditCards().size());
+  EXPECT_EQ(u"Keep", personal_data_->GetProfiles()[0]->GetRawInfo(NAME_LAST));
+  EXPECT_EQ(u"Keep", personal_data_->GetProfiles()[1]->GetRawInfo(NAME_LAST));
+  EXPECT_EQ(u"Keep", personal_data_->GetProfiles()[2]->GetRawInfo(NAME_LAST));
+}
+
+// Tests that DeleteDisusedCreditCards deletes desired credit cards only.
+TEST_F(PersonalDataManagerCleanerTest,
+       DeleteDisusedCreditCards_OnlyDeleteExpiredDisusedLocalCards) {
+  const char kHistogramName[] = "Autofill.CreditCardsDeletedForDisuse";
+  auto now = AutofillClock::Now();
+
+  // Create a recently used local card, it is expected to remain.
+  CreditCard credit_card1(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetCreditCardInfo(&credit_card1, "Alice",
+                          "378282246310005" /* American Express */, "04",
+                          "2999", "1");
+  credit_card1.set_use_date(now - base::Days(4));
+
+  // Create a local card that was expired 400 days ago, but recently used.
+  // It is expected to remain.
+  CreditCard credit_card2(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetCreditCardInfo(&credit_card2, "Bob",
+                          "378282246310006" /* American Express */, "04",
+                          "1999", "1");
+  credit_card2.set_use_date(now - base::Days(4));
+
+  // Create a local card expired recently, and last used 400 days ago.
+  // It is expected to remain.
+  CreditCard credit_card3(base::GenerateGUID(), test::kEmptyOrigin);
+  base::Time expiry_date = now - base::Days(32);
+  base::Time::Exploded exploded;
+  expiry_date.UTCExplode(&exploded);
+  test::SetCreditCardInfo(&credit_card3, "Clyde", "4111111111111111" /* Visa */,
+                          base::StringPrintf("%02d", exploded.month).c_str(),
+                          base::StringPrintf("%04d", exploded.year).c_str(),
+                          "1");
+  credit_card3.set_use_date(now - base::Days(400));
+
+  // Create a local card expired 400 days ago, and last used 400 days ago.
+  // It is expected to be deleted.
+  CreditCard credit_card4(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetCreditCardInfo(&credit_card4, "David",
+                          "5105105105105100" /* Mastercard */, "04", "1999",
+                          "1");
+  credit_card4.set_use_date(now - base::Days(400));
+  personal_data_->AddCreditCard(credit_card1);
+  personal_data_->AddCreditCard(credit_card2);
+  personal_data_->AddCreditCard(credit_card3);
+  personal_data_->AddCreditCard(credit_card4);
+
+  // Create a unmasked server card expired 400 days ago, and last used 400
+  // days ago.
+  // It is expected to remain because we do not delete server cards.
+  CreditCard credit_card5(CreditCard::FULL_SERVER_CARD, "c789");
+  test::SetCreditCardInfo(&credit_card5, "Emma", "4234567890123456" /* Visa */,
+                          "04", "1999", "1");
+  credit_card5.set_use_date(now - base::Days(400));
+
+  // Create masked server card expired 400 days ago, and last used 400 days ago.
+  // It is expected to remain because we do not delete server cards.
+  CreditCard credit_card6(CreditCard::MASKED_SERVER_CARD, "c987");
+  test::SetCreditCardInfo(&credit_card6, "Frank", "6543", "01", "1998", "1");
+  credit_card6.set_use_date(now - base::Days(400));
+  credit_card6.SetNetworkForMaskedCard(kVisaCard);
+
+  // Save the server cards and set used_date to desired dates.
+  std::vector<CreditCard> server_cards;
+  server_cards.push_back(credit_card5);
+  server_cards.push_back(credit_card6);
+  SetServerCards(server_cards);
+  personal_data_->UpdateServerCardsMetadata({credit_card5, credit_card6});
+
+  WaitForOnPersonalDataChanged();
+  EXPECT_EQ(6U, personal_data_->GetCreditCards().size());
+
+  // Setup histograms capturing.
+  base::HistogramTester histogram_tester;
+
+  // DeleteDisusedCreditCards should return true to indicate it was run.
+  EXPECT_TRUE(
+      personal_data_manager_cleaner_->DeleteDisusedCreditCardsForTesting());
+
+  // Wait for the data to be refreshed.
+  WaitForOnPersonalDataChanged();
+
+  EXPECT_EQ(5U, personal_data_->GetCreditCards().size());
+  std::unordered_set<std::u16string> expectedToRemain = {
+      u"Alice", u"Bob", u"Clyde", u"Emma", u"Frank"};
+  for (auto* card : personal_data_->GetCreditCards()) {
+    EXPECT_NE(expectedToRemain.end(),
+              expectedToRemain.find(card->GetRawInfo(CREDIT_CARD_NAME_FULL)));
+  }
+
+  // Verify histograms are logged.
+  histogram_tester.ExpectTotalCount(kHistogramName, 1);
+  histogram_tester.ExpectBucketCount(kHistogramName, 1, 1);
+}
+
+// Tests that all the non settings origins of autofill profiles are cleared but
+// that the settings origins are untouched.
+TEST_F(PersonalDataManagerCleanerTest, ClearProfileNonSettingsOrigins) {
+  // Create three profile with a nonsettings, non-empty origin.
+  AutofillProfile profile0(base::GenerateGUID(), "https://www.example.com");
+  test::SetProfileInfo(&profile0, "Marion0", "Mitchell", "Morrison",
+                       "johnwayne@me.xyz", "Fox",
+                       "123 Zoo St.\nSecond Line\nThird line", "unit 5",
+                       "Hollywood", "CA", "91601", "US", "12345678910");
+  profile0.set_use_count(10000);
+  AddProfileToPersonalDataManager(profile0);
+
+  AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetProfileInfo(&profile1, "Marion1", "Mitchell", "Morrison",
+                       "johnwayne@me.xyz", "Fox",
+                       "123 Zoo St.\nSecond Line\nThird line", "unit 5",
+                       "Hollywood", "CA", "91601", "US", "12345678910");
+  profile1.set_use_count(1000);
+  AddProfileToPersonalDataManager(profile1);
+
+  AutofillProfile profile2(base::GenerateGUID(), "1234");
+  test::SetProfileInfo(&profile2, "Marion2", "Mitchell", "Morrison",
+                       "johnwayne@me.xyz", "Fox",
+                       "123 Zoo St.\nSecond Line\nThird line", "unit 5",
+                       "Hollywood", "CA", "91601", "US", "12345678910");
+  profile2.set_use_count(100);
+  AddProfileToPersonalDataManager(profile2);
+
+  // Create a profile with a settings origin.
+  AutofillProfile profile3(base::GenerateGUID(), kSettingsOrigin);
+  test::SetProfileInfo(&profile3, "Marion3", "Mitchell", "Morrison",
+                       "johnwayne@me.xyz", "Fox",
+                       "123 Zoo St.\nSecond Line\nThird line", "unit 5",
+                       "Hollywood", "CA", "91601", "US", "12345678910");
+  profile3.set_use_count(10);
+  AddProfileToPersonalDataManager(profile3);
+
+  ASSERT_EQ(4U, personal_data_->GetProfiles().size());
+
+  base::RunLoop run_loop;
+  EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
+      .WillRepeatedly(QuitMessageLoop(&run_loop));
+  EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
+      .Times(2);  // The setting of profiles 0 and 2 will be cleared.
+
+  personal_data_manager_cleaner_->ClearProfileNonSettingsOriginsForTesting();
+  run_loop.Run();
+
+  ASSERT_EQ(4U, personal_data_->GetProfiles().size());
+
+  // The first three profiles' origin should be cleared and the fourth one still
+  // be the settings origin.
+  EXPECT_TRUE(personal_data_->GetProfilesToSuggest()[0]->origin().empty());
+  EXPECT_TRUE(personal_data_->GetProfilesToSuggest()[1]->origin().empty());
+  EXPECT_TRUE(personal_data_->GetProfilesToSuggest()[2]->origin().empty());
+  EXPECT_EQ(kSettingsOrigin,
+            personal_data_->GetProfilesToSuggest()[3]->origin());
+}
+
+// Tests that all the non settings origins of autofill credit cards are cleared
+// but that the settings origins are untouched.
+TEST_F(PersonalDataManagerCleanerTest, ClearCreditCardNonSettingsOrigins) {
+  // Create three cards with a non settings origin.
+  CreditCard credit_card0(base::GenerateGUID(), "https://www.example.com");
+  test::SetCreditCardInfo(&credit_card0, "Bob0",
+                          "5105105105105100" /* Mastercard */, "04", "1999",
+                          "1");
+  credit_card0.set_use_count(10000);
+  personal_data_->AddCreditCard(credit_card0);
+
+  CreditCard credit_card1(base::GenerateGUID(), test::kEmptyOrigin);
+  test::SetCreditCardInfo(&credit_card1, "Bob1",
+                          "5105105105105101" /* Mastercard */, "04", "1999",
+                          "1");
+  credit_card1.set_use_count(1000);
+  personal_data_->AddCreditCard(credit_card1);
+
+  CreditCard credit_card2(base::GenerateGUID(), "1234");
+  test::SetCreditCardInfo(&credit_card2, "Bob2",
+                          "5105105105105102" /* Mastercard */, "04", "1999",
+                          "1");
+  credit_card2.set_use_count(100);
+  personal_data_->AddCreditCard(credit_card2);
+
+  // Create a card with a settings origin.
+  CreditCard credit_card3(base::GenerateGUID(), kSettingsOrigin);
+  test::SetCreditCardInfo(&credit_card3, "Bob3",
+                          "5105105105105103" /* Mastercard */, "04", "1999",
+                          "1");
+  credit_card3.set_use_count(10);
+  personal_data_->AddCreditCard(credit_card3);
+
+  WaitForOnPersonalDataChanged();
+  ASSERT_EQ(4U, personal_data_->GetCreditCards().size());
+
+  personal_data_manager_cleaner_->ClearCreditCardNonSettingsOriginsForTesting();
+
+  WaitForOnPersonalDataChanged();
+  ASSERT_EQ(4U, personal_data_->GetCreditCards().size());
+
+  // The first three profiles' origin should be cleared and the fourth one still
+  // be the settings origin.
+  EXPECT_TRUE(
+      personal_data_->GetCreditCardsToSuggest(false)[0]->origin().empty());
+  EXPECT_TRUE(
+      personal_data_->GetCreditCardsToSuggest(false)[1]->origin().empty());
+  EXPECT_TRUE(
+      personal_data_->GetCreditCardsToSuggest(false)[2]->origin().empty());
+  EXPECT_EQ(kSettingsOrigin,
+            personal_data_->GetCreditCardsToSuggest(false)[3]->origin());
+}
+
+}  // namespace autofill
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc
index 236e11bc..189f6c6 100644
--- a/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -3853,1090 +3853,6 @@
   EXPECT_EQ(kMuchLaterTime, profiles[0].modification_date());
 }
 
-// Tests that DedupeProfiles sets the correct profile guids to
-// delete after merging similar profiles.
-TEST_F(PersonalDataManagerTest, DedupeProfiles_ProfilesToDelete) {
-  // Create the profile for which to find duplicates. It has the highest
-  // ranking score.
-  AutofillProfile* profile1 =
-      new AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(profile1, "Homer", "Jay", "Simpson",
-                       "homer.simpson@abc.com", "", "742. Evergreen Terrace",
-                       "", "Springfield", "IL", "91601", "US", "12345678910");
-  profile1->set_use_count(9);
-
-  // Create a different profile that should not be deduped (different address).
-  AutofillProfile* profile2 =
-      new AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(profile2, "Homer", "Jay", "Simpson",
-                       "homer.simpson@abc.com", "Fox", "1234 Other Street", "",
-                       "Springfield", "IL", "91601", "US", "12345678910");
-  profile2->set_use_count(7);
-
-  // Create a profile similar to profile1 which should be deduped.
-  AutofillProfile* profile3 =
-      new AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(profile3, "Homer", "Jay", "Simpson",
-                       "homer.simpson@abc.com", "", "742 Evergreen Terrace", "",
-                       "Springfield", "IL", "91601", "US", "12345678910");
-  profile3->set_use_count(5);
-
-  // Create another different profile that should not be deduped (different
-  // name).
-  AutofillProfile* profile4 =
-      new AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(profile4, "Marjorie", "Jacqueline", "Simpson",
-                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace",
-                       "", "Springfield", "IL", "91601", "US", "12345678910");
-  profile4->set_use_count(3);
-
-  // Create another profile similar to profile1. Since that one has the lowest
-  // ranking score, the result of the merge should be in this profile at the end
-  // of the test.
-  AutofillProfile* profile5 =
-      new AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(profile5, "Homer", "Jay", "Simpson",
-                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
-                       "", "Springfield", "IL", "91601", "US", "12345678910");
-  profile5->set_use_count(1);
-
-  // Add the profiles.
-  std::vector<std::unique_ptr<AutofillProfile>> existing_profiles;
-  existing_profiles.push_back(std::unique_ptr<AutofillProfile>(profile1));
-  existing_profiles.push_back(std::unique_ptr<AutofillProfile>(profile2));
-  existing_profiles.push_back(std::unique_ptr<AutofillProfile>(profile3));
-  existing_profiles.push_back(std::unique_ptr<AutofillProfile>(profile4));
-  existing_profiles.push_back(std::unique_ptr<AutofillProfile>(profile5));
-
-  base::HistogramTester histogram_tester;
-  std::unordered_map<std::string, std::string> guids_merge_map;
-  std::unordered_set<std::string> profiles_to_delete;
-  personal_data_->personal_data_manager_cleaner_for_testing()
-      ->DedupeProfilesForTesting(&existing_profiles, &profiles_to_delete,
-                                 &guids_merge_map);
-  // 5 profiles were considered for dedupe.
-  histogram_tester.ExpectUniqueSample(
-      "Autofill.NumberOfProfilesConsideredForDedupe", 5, 1);
-  // 2 profiles were removed (profiles 1 and 3).
-  histogram_tester.ExpectUniqueSample(
-      "Autofill.NumberOfProfilesRemovedDuringDedupe", 2, 1);
-
-  // Profile1 should be deleted because it was sent as the profile to merge and
-  // thus was merged into profile3 and then into profile5.
-  EXPECT_TRUE(profiles_to_delete.count(profile1->guid()));
-
-  // Profile3 should be deleted because profile1 was merged into it and the
-  // resulting profile was then merged into profile5.
-  EXPECT_TRUE(profiles_to_delete.count(profile3->guid()));
-
-  // Only these two profiles should be deleted.
-  EXPECT_EQ(2U, profiles_to_delete.size());
-
-  // All profiles should still be present in |existing_profiles|.
-  EXPECT_EQ(5U, existing_profiles.size());
-}
-
-// Tests that DedupeProfiles sets the correct merge mapping for billing address
-// id references.
-TEST_F(PersonalDataManagerTest, DedupeProfiles_GuidsMergeMap) {
-  // Create the profile for which to find duplicates. It has the highest
-  // ranking score.
-  AutofillProfile* profile1 =
-      new AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(profile1, "Homer", "Jay", "Simpson",
-                       "homer.simpson@abc.com", "", "742. Evergreen Terrace",
-                       "", "Springfield", "IL", "91601", "US", "12345678910");
-  profile1->set_use_count(9);
-
-  // Create a different profile that should not be deduped (different address).
-  AutofillProfile* profile2 =
-      new AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(profile2, "Homer", "Jay", "Simpson",
-                       "homer.simpson@abc.com", "Fox", "1234 Other Street", "",
-                       "Springfield", "IL", "91601", "US", "12345678910");
-  profile2->set_use_count(7);
-
-  // Create a profile similar to profile1 which should be deduped.
-  AutofillProfile* profile3 =
-      new AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(profile3, "Homer", "Jay", "Simpson",
-                       "homer.simpson@abc.com", "", "742 Evergreen Terrace", "",
-                       "Springfield", "IL", "91601", "US", "12345678910");
-  profile3->set_use_count(5);
-
-  // Create another different profile that should not be deduped (different
-  // name).
-  AutofillProfile* profile4 =
-      new AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(profile4, "Marjorie", "Jacqueline", "Simpson",
-                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace",
-                       "", "Springfield", "IL", "91601", "US", "12345678910");
-  profile4->set_use_count(3);
-
-  // Create another profile similar to profile1. Since that one has the lowest
-  // ranking score, the result of the merge should be in this profile at the end
-  // of the test.
-  AutofillProfile* profile5 =
-      new AutofillProfile(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(profile5, "Homer", "Jay", "Simpson",
-                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
-                       "", "Springfield", "IL", "91601", "US", "12345678910");
-  profile5->set_use_count(1);
-
-  // Add the profiles.
-  std::vector<std::unique_ptr<AutofillProfile>> existing_profiles;
-  existing_profiles.push_back(std::unique_ptr<AutofillProfile>(profile1));
-  existing_profiles.push_back(std::unique_ptr<AutofillProfile>(profile2));
-  existing_profiles.push_back(std::unique_ptr<AutofillProfile>(profile3));
-  existing_profiles.push_back(std::unique_ptr<AutofillProfile>(profile4));
-  existing_profiles.push_back(std::unique_ptr<AutofillProfile>(profile5));
-
-  std::unordered_map<std::string, std::string> guids_merge_map;
-  std::unordered_set<std::string> profiles_to_delete;
-
-  personal_data_->personal_data_manager_cleaner_for_testing()
-      ->DedupeProfilesForTesting(&existing_profiles, &profiles_to_delete,
-                                 &guids_merge_map);
-
-  // The two profile merges should be recorded in the map.
-  EXPECT_EQ(2U, guids_merge_map.size());
-
-  // Profile 1 was merged into profile 3.
-  ASSERT_TRUE(guids_merge_map.count(profile1->guid()));
-  EXPECT_TRUE(guids_merge_map.at(profile1->guid()) == profile3->guid());
-
-  // Profile 3 was merged into profile 5.
-  ASSERT_TRUE(guids_merge_map.count(profile3->guid()));
-  EXPECT_TRUE(guids_merge_map.at(profile3->guid()) == profile5->guid());
-}
-
-// Tests that UpdateCardsBillingAddressReference sets the correct billing
-// address id as specified in the map.
-TEST_F(PersonalDataManagerTest, UpdateCardsBillingAddressReference) {
-  /*  The merges will be as follow:
-
-      A -> B            F (not merged)
-             \
-               -> E
-             /
-      C -> D
-  */
-
-  std::unordered_map<std::string, std::string> guids_merge_map;
-  guids_merge_map.insert(std::pair<std::string, std::string>("A", "B"));
-  guids_merge_map.insert(std::pair<std::string, std::string>("C", "D"));
-  guids_merge_map.insert(std::pair<std::string, std::string>("B", "E"));
-  guids_merge_map.insert(std::pair<std::string, std::string>("D", "E"));
-
-  // Create a credit card without a billing address id
-  CreditCard* credit_card0 =
-      new CreditCard(base::GenerateGUID(), test::kEmptyOrigin);
-
-  // Create cards that use A, D, E and F as their billing address id.
-  CreditCard* credit_card1 =
-      new CreditCard(base::GenerateGUID(), test::kEmptyOrigin);
-  credit_card1->set_billing_address_id("A");
-  CreditCard* credit_card2 =
-      new CreditCard(base::GenerateGUID(), test::kEmptyOrigin);
-  credit_card2->set_billing_address_id("D");
-  CreditCard* credit_card3 =
-      new CreditCard(base::GenerateGUID(), test::kEmptyOrigin);
-  credit_card3->set_billing_address_id("E");
-  CreditCard* credit_card4 =
-      new CreditCard(base::GenerateGUID(), test::kEmptyOrigin);
-  credit_card4->set_billing_address_id("F");
-
-  // Add the credit cards to the database.
-  personal_data_->local_credit_cards_.push_back(
-      std::unique_ptr<CreditCard>(credit_card0));
-  personal_data_->local_credit_cards_.push_back(
-      std::unique_ptr<CreditCard>(credit_card1));
-  personal_data_->server_credit_cards_.push_back(
-      std::unique_ptr<CreditCard>(credit_card2));
-  personal_data_->local_credit_cards_.push_back(
-      std::unique_ptr<CreditCard>(credit_card3));
-  personal_data_->server_credit_cards_.push_back(
-      std::unique_ptr<CreditCard>(credit_card4));
-
-  personal_data_->personal_data_manager_cleaner_for_testing()
-      ->UpdateCardsBillingAddressReferenceForTesting(guids_merge_map);
-
-  // The first card's billing address should now be E.
-  EXPECT_EQ("E", credit_card1->billing_address_id());
-  // The second card's billing address should now be E.
-  EXPECT_EQ("E", credit_card2->billing_address_id());
-  // The third card's billing address should still be E.
-  EXPECT_EQ("E", credit_card3->billing_address_id());
-  // The fourth card's billing address should still be F.
-  EXPECT_EQ("F", credit_card4->billing_address_id());
-}
-
-// Tests that ApplyDedupingRoutine updates the credit cards' billing address id
-// based on the deduped profiles.
-TEST_F(PersonalDataManagerTest,
-       ApplyDedupingRoutine_CardsBillingAddressIdUpdated) {
-  base::test::ScopedFeatureList feature;
-  feature.InitAndEnableFeature(features::kAutofillEnableProfileDeduplication);
-
-  // A set of 6 profiles will be created. They should merge in this way:
-  //  1 -> 2 -> 3
-  //  4 -> 5
-  //  6
-  // Set their frencency score so that profile 3 has a higher score than 5, and
-  // 5 has a higher score than 6. This will ensure a deterministic order when
-  // verifying results.
-
-  // Create a set of 3 profiles to be merged together.
-  // Create a profile with a higher ranking score.
-  AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile1, "Homer", "J", "Simpson",
-                       "homer.simpson@abc.com", "", "742. Evergreen Terrace",
-                       "", "Springfield", "IL", "91601", "US", "");
-  profile1.set_use_count(12);
-  profile1.set_use_date(AutofillClock::Now() - base::Days(1));
-
-  // Create a profile with a medium ranking score.
-  AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile2, "Homer", "Jay", "Simpson",
-                       "homer.simpson@abc.com", "", "742 Evergreen Terrace", "",
-                       "Springfield", "IL", "91601", "", "12345678910");
-  profile2.set_use_count(5);
-  profile2.set_use_date(AutofillClock::Now() - base::Days(3));
-
-  // Create a profile with a lower ranking score.
-  AutofillProfile profile3(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile3, "Homer", "J", "Simpson",
-                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
-                       "", "Springfield", "IL", "91601", "", "");
-  profile3.set_use_count(3);
-  profile3.set_use_date(AutofillClock::Now() - base::Days(5));
-
-  // Create a set of two profiles to be merged together.
-  // Create a profile with a higher ranking score.
-  AutofillProfile profile4(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile4, "Marge", "B", "Simpson",
-                       "marge.simpson@abc.com", "", "742. Evergreen Terrace",
-                       "", "Springfield", "IL", "91601", "US", "");
-  profile4.set_use_count(11);
-  profile4.set_use_date(AutofillClock::Now() - base::Days(1));
-
-  // Create a profile with a lower ranking score.
-  AutofillProfile profile5(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile5, "Marge", "B", "Simpson",
-                       "marge.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
-                       "", "Springfield", "IL", "91601", "", "");
-  profile5.set_use_count(5);
-  profile5.set_use_date(AutofillClock::Now() - base::Days(3));
-
-  // Create a unique profile.
-  AutofillProfile profile6(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile6, "Bart", "J", "Simpson",
-                       "bart.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
-                       "", "Springfield", "IL", "91601", "", "");
-  profile6.set_use_count(10);
-  profile6.set_use_date(AutofillClock::Now() - base::Days(1));
-
-  // Add three credit cards. Give them a ranking score so that they are
-  // suggested in order (1, 2, 3). This will ensure a deterministic order for
-  // verifying results.
-  CreditCard credit_card1(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetCreditCardInfo(&credit_card1, "Clyde Barrow",
-                          "378282246310005" /* American Express */, "04",
-                          "2999", "1");
-  credit_card1.set_use_count(10);
-
-  CreditCard credit_card2(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetCreditCardInfo(&credit_card2, "John Dillinger",
-                          "4234567890123456" /* Visa */, "01", "2999", "1");
-  credit_card2.set_use_count(5);
-
-  CreditCard credit_card3(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetCreditCardInfo(&credit_card3, "Bonnie Parker",
-                          "5105105105105100" /* Mastercard */, "12", "2999",
-                          "1");
-  credit_card3.set_use_count(1);
-
-  // Associate the first card with profile1.
-  credit_card1.set_billing_address_id(profile1.guid());
-  // Associate the second card with profile4.
-  credit_card2.set_billing_address_id(profile4.guid());
-  // Associate the third card with profile6.
-  credit_card3.set_billing_address_id(profile6.guid());
-
-  AddProfileToPersonalDataManager(profile1);
-  AddProfileToPersonalDataManager(profile2);
-  AddProfileToPersonalDataManager(profile3);
-  AddProfileToPersonalDataManager(profile4);
-  AddProfileToPersonalDataManager(profile5);
-  AddProfileToPersonalDataManager(profile6);
-  personal_data_->AddCreditCard(credit_card1);
-  personal_data_->AddCreditCard(credit_card2);
-  personal_data_->AddCreditCard(credit_card3);
-
-  WaitForOnPersonalDataChanged();
-
-  // Make sure the 6 profiles and 3 credit cards were saved.
-  EXPECT_EQ(6U, personal_data_->GetProfiles().size());
-  EXPECT_EQ(3U, personal_data_->GetCreditCards().size());
-
-  EXPECT_TRUE(personal_data_->personal_data_manager_cleaner_for_testing()
-                  ->ApplyDedupingRoutineForTesting());
-  WaitForOnPersonalDataChanged();
-
-  // Get the profiles and cards sorted by their ranking score to have a
-  // deterministic order.
-  std::vector<AutofillProfile*> profiles =
-      personal_data_->GetProfilesToSuggest();
-  std::vector<CreditCard*> credit_cards =
-      personal_data_->GetCreditCardsToSuggest(/*include_server_cards=*/true);
-
-  // |profile1| should have been merged into |profile2| which should then have
-  // been merged into |profile3|. |profile4| should have been merged into
-  // |profile5| and |profile6| should not have merged. Therefore there should be
-  // 3 profile left.
-  ASSERT_EQ(3U, profiles.size());
-
-  // Make sure the remaining profiles are the expected ones.
-  EXPECT_EQ(profile3.guid(), profiles[0]->guid());
-  EXPECT_EQ(profile5.guid(), profiles[1]->guid());
-  EXPECT_EQ(profile6.guid(), profiles[2]->guid());
-
-  // |credit_card1|'s billing address should now be profile 3.
-  EXPECT_EQ(profile3.guid(), credit_cards[0]->billing_address_id());
-
-  // |credit_card2|'s billing address should now be profile 5.
-  EXPECT_EQ(profile5.guid(), credit_cards[1]->billing_address_id());
-
-  // |credit_card3|'s billing address should still be profile 6.
-  EXPECT_EQ(profile6.guid(), credit_cards[2]->billing_address_id());
-}
-
-// Tests that ApplyDedupingRoutine merges the profile values correctly, i.e.
-// never lose information and keep the syntax of the profile with the higher
-// ranking score.
-TEST_F(PersonalDataManagerTest, ApplyDedupingRoutine_MergedProfileValues) {
-  base::test::ScopedFeatureList feature;
-  feature.InitAndEnableFeature(features::kAutofillEnableProfileDeduplication);
-
-  // Create a profile with a higher ranking score.
-  AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile1, "Homer", "J", "Simpson",
-                       "homer.simpson@abc.com", "", "742. Evergreen Terrace",
-                       "", "Springfield", "IL", "91601", "US", "");
-  profile1.set_use_count(10);
-  profile1.set_use_date(AutofillClock::Now() - base::Days(1));
-
-  // Create a profile with a medium ranking score.
-  AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile2, "Homer", "Jay", "Simpson",
-                       "homer.simpson@abc.com", "", "742 Evergreen Terrace", "",
-                       "Springfield", "IL", "91601", "", "12345678910");
-  profile2.set_use_count(5);
-  profile2.set_use_date(AutofillClock::Now() - base::Days(3));
-
-  // Create a profile with a lower ranking score.
-  AutofillProfile profile3(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile3, "Homer", "J", "Simpson",
-                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
-                       "", "Springfield", "IL", "91601", "", "");
-  profile3.set_use_count(3);
-  profile3.set_use_date(AutofillClock::Now() - base::Days(5));
-
-  AddProfileToPersonalDataManager(profile1);
-  AddProfileToPersonalDataManager(profile2);
-  AddProfileToPersonalDataManager(profile3);
-
-  // Make sure the 3 profiles were saved;
-  EXPECT_EQ(3U, personal_data_->GetProfiles().size());
-
-  base::HistogramTester histogram_tester;
-
-  EXPECT_TRUE(personal_data_->personal_data_manager_cleaner_for_testing()
-                  ->ApplyDedupingRoutineForTesting());
-  WaitForOnPersonalDataChanged();
-
-  std::vector<AutofillProfile*> profiles = personal_data_->GetProfiles();
-
-  // |profile1| should have been merged into |profile2| which should then have
-  // been merged into |profile3|. Therefore there should only be 1 saved
-  // profile.
-  ASSERT_EQ(1U, profiles.size());
-  // 3 profiles were considered for dedupe.
-  histogram_tester.ExpectUniqueSample(
-      "Autofill.NumberOfProfilesConsideredForDedupe", 3, 1);
-  // 2 profiles were removed (profiles 1 and 2).
-  histogram_tester.ExpectUniqueSample(
-      "Autofill.NumberOfProfilesRemovedDuringDedupe", 2, 1);
-
-  // Since profiles with higher ranking scores are merged into profiles with
-  // lower ranking scores, the result of the merge should be contained in
-  // profile3 since it had a lower ranking score compared to profile1.
-  EXPECT_EQ(profile3.guid(), profiles[0]->guid());
-  // The address syntax that results from the merge should be the one from the
-  // imported profile (highest ranking).
-  EXPECT_EQ(u"742. Evergreen Terrace",
-            profiles[0]->GetRawInfo(ADDRESS_HOME_LINE1));
-  // The middle name should be full, even if the profile with the higher
-  // ranking only had an initial (no loss of information).
-  EXPECT_EQ(u"Jay", profiles[0]->GetRawInfo(NAME_MIDDLE));
-  // The specified phone number from profile1 should be kept (no loss of
-  // information).
-  EXPECT_EQ(u"12345678910", profiles[0]->GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
-  // The specified company name from profile2 should be kept (no loss of
-  // information).
-  EXPECT_EQ(u"Fox", profiles[0]->GetRawInfo(COMPANY_NAME));
-  // The specified country from the imported profile shoudl be kept (no loss of
-  // information).
-  EXPECT_EQ(u"US", profiles[0]->GetRawInfo(ADDRESS_HOME_COUNTRY));
-  // The use count that results from the merge should be the max of all the
-  // profiles use counts.
-  EXPECT_EQ(10U, profiles[0]->use_count());
-  // The use date that results from the merge should be the one from the
-  // profile1 since it was the most recently used profile.
-  EXPECT_LT(profile1.use_date() - base::Seconds(10), profiles[0]->use_date());
-}
-
-// Tests that ApplyDedupingRoutine only keeps the verified profile with its
-// original data when deduping with similar profiles, even if it has a higher
-// ranking score.
-TEST_F(PersonalDataManagerTest, ApplyDedupingRoutine_VerifiedProfileFirst) {
-  base::test::ScopedFeatureList feature;
-  feature.InitAndEnableFeature(features::kAutofillEnableProfileDeduplication);
-
-  // Create a verified profile with a higher ranking score.
-  AutofillProfile profile1(base::GenerateGUID(), kSettingsOrigin);
-  test::SetProfileInfo(
-      &profile1, "Homer", "Jay", "Simpson", "homer.simpson@abc.com", "",
-      "742 Evergreen Terrace", "", "Springfield", "IL", "91601", "",
-      "12345678910", /*finalize=*/true,
-      /*status=*/structured_address::VerificationStatus::kUserVerified);
-  profile1.set_use_count(7);
-  profile1.set_use_date(kMuchLaterTime);
-
-  // Create a similar non verified profile with a medium ranking score.
-  AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile2, "Homer", "J", "Simpson",
-                       "homer.simpson@abc.com", "", "742. Evergreen Terrace",
-                       "", "Springfield", "IL", "91601", "US", "");
-  profile2.set_use_count(5);
-  profile2.set_use_date(kSomeLaterTime);
-
-  // Create a similar non verified profile with a lower ranking score.
-  AutofillProfile profile3(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile3, "Homer", "J", "Simpson",
-                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
-                       "", "Springfield", "IL", "91601", "", "");
-  profile3.set_use_count(3);
-  profile3.set_use_date(kArbitraryTime);
-
-  AddProfileToPersonalDataManager(profile1);
-  AddProfileToPersonalDataManager(profile2);
-  AddProfileToPersonalDataManager(profile3);
-
-  // Make sure the 3 profiles were saved.
-  EXPECT_EQ(3U, personal_data_->GetProfiles().size());
-
-  base::HistogramTester histogram_tester;
-
-  EXPECT_TRUE(personal_data_->personal_data_manager_cleaner_for_testing()
-                  ->ApplyDedupingRoutineForTesting());
-  WaitForOnPersonalDataChanged();
-
-  std::vector<AutofillProfile*> profiles = personal_data_->GetProfiles();
-
-  // |profile2| should have merged with |profile3|. |profile3|
-  // should then have been discarded because it is similar to the verified
-  // |profile1|.
-  ASSERT_EQ(1U, profiles.size());
-  // 3 profiles were considered for dedupe.
-  histogram_tester.ExpectUniqueSample(
-      "Autofill.NumberOfProfilesConsideredForDedupe", 3, 1);
-  // 2 profile were removed (profiles 2 and 3).
-  histogram_tester.ExpectUniqueSample(
-      "Autofill.NumberOfProfilesRemovedDuringDedupe", 2, 1);
-
-  // Although the profile was verified, the structure of the  street address
-  // still evolved with future observations. In this case, the "." was added
-  // from a later observation.
-  profile1.SetRawInfoWithVerificationStatus(
-      ADDRESS_HOME_STREET_NAME, u"Evergreen Terrace",
-      structured_address::VerificationStatus::kParsed);
-  //
-  // Only the verified |profile1| with its original data should have been kept.
-  EXPECT_EQ(profile1.guid(), profiles[0]->guid());
-  EXPECT_TRUE(profile1 == *profiles[0]);
-  EXPECT_EQ(profile1.use_count(), profiles[0]->use_count());
-  EXPECT_EQ(profile1.use_date(), profiles[0]->use_date());
-}
-
-// Tests that ApplyDedupingRoutine only keeps the verified profile with its
-// original data when deduping with similar profiles, even if it has a lower
-// ranking score.
-TEST_F(PersonalDataManagerTest, ApplyDedupingRoutine_VerifiedProfileLast) {
-  base::test::ScopedFeatureList feature;
-  feature.InitAndEnableFeature(features::kAutofillEnableProfileDeduplication);
-
-  // Create a profile to dedupe with a higher ranking score.
-  AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile1, "Homer", "J", "Simpson",
-                       "homer.simpson@abc.com", "", "742. Evergreen Terrace",
-                       "", "Springfield", "IL", "91601", "US", "");
-  profile1.set_use_count(5);
-  profile1.set_use_date(kMuchLaterTime);
-
-  // Create a similar non verified profile with a medium ranking score.
-  AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile2, "Homer", "J", "Simpson",
-                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
-                       "", "Springfield", "IL", "91601", "", "");
-  profile2.set_use_count(5);
-  profile2.set_use_date(kSomeLaterTime);
-
-  // Create a similar verified profile with a lower ranking score.
-  AutofillProfile profile3(base::GenerateGUID(), kSettingsOrigin);
-  test::SetProfileInfo(
-      &profile3, "Homer", "Jay", "Simpson", "homer.simpson@abc.com", "",
-      "742 Evergreen Terrace", "", "Springfield", "IL", "91601", "",
-      "12345678910", /*finalize=*/true,
-      /*status=*/structured_address::VerificationStatus::kUserVerified);
-  profile3.set_use_count(3);
-  profile3.set_use_date(kArbitraryTime);
-
-  AddProfileToPersonalDataManager(profile1);
-  AddProfileToPersonalDataManager(profile2);
-  AddProfileToPersonalDataManager(profile3);
-
-  // Make sure the 3 profiles were saved.
-  EXPECT_EQ(3U, personal_data_->GetProfiles().size());
-
-  base::HistogramTester histogram_tester;
-
-  EXPECT_TRUE(personal_data_->personal_data_manager_cleaner_for_testing()
-                  ->ApplyDedupingRoutineForTesting());
-  WaitForOnPersonalDataChanged();
-
-  std::vector<AutofillProfile*> profiles = personal_data_->GetProfiles();
-
-  // |profile1| should have merged with |profile2|. |profile2|
-  // should then have been discarded because it is similar to the verified
-  // |profile3|.
-  ASSERT_EQ(1U, profiles.size());
-  // 3 profiles were considered for dedupe.
-  histogram_tester.ExpectUniqueSample(
-      "Autofill.NumberOfProfilesConsideredForDedupe", 3, 1);
-  // 2 profile were removed (profiles 1 and 2).
-  histogram_tester.ExpectUniqueSample(
-      "Autofill.NumberOfProfilesRemovedDuringDedupe", 2, 1);
-
-  // Only the verified |profile3| with it's original data should have been kept.
-  EXPECT_EQ(profile3.guid(), profiles[0]->guid());
-  EXPECT_TRUE(profile3 == *profiles[0]);
-  EXPECT_EQ(profile3.use_count(), profiles[0]->use_count());
-  EXPECT_EQ(profile3.use_date(), profiles[0]->use_date());
-}
-
-// Tests that ApplyDedupingRoutine does not merge unverified data into
-// a verified profile. Also tests that two verified profiles don't get merged.
-TEST_F(PersonalDataManagerTest, ApplyDedupingRoutine_MultipleVerifiedProfiles) {
-  base::test::ScopedFeatureList feature;
-  feature.InitAndEnableFeature(features::kAutofillEnableProfileDeduplication);
-
-  // Create a profile to dedupe with a higher ranking score.
-  AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile1, "Homer", "J", "Simpson",
-                       "homer.simpson@abc.com", "", "742. Evergreen Terrace",
-                       "", "Springfield", "IL", "91601", "US", "");
-  profile1.set_use_count(5);
-  profile1.set_use_date(kMuchLaterTime);
-
-  // Create a similar verified profile with a medium ranking score.
-  AutofillProfile profile2(base::GenerateGUID(), kSettingsOrigin);
-  test::SetProfileInfo(
-      &profile2, "Homer", "J", "Simpson", "homer.simpson@abc.com", "Fox",
-      "742 Evergreen Terrace.", "", "Springfield", "IL", "91601", "", "",
-      /*finalize=*/true,
-      /*status=*/structured_address::VerificationStatus::kUserVerified);
-
-  profile2.set_use_count(5);
-  profile2.set_use_date(kSomeLaterTime);
-
-  // Create a similar verified profile with a lower ranking score.
-  AutofillProfile profile3(base::GenerateGUID(), kSettingsOrigin);
-  test::SetProfileInfo(
-      &profile3, "Homer", "Jay", "Simpson", "homer.simpson@abc.com", "",
-      "742 Evergreen Terrace", "", "Springfield", "IL", "91601", "",
-      "12345678910", /*finalize=*/true,
-      /*status*/ structured_address::VerificationStatus::kUserVerified);
-  profile3.set_use_count(3);
-  profile3.set_use_date(kArbitraryTime);
-
-  AddProfileToPersonalDataManager(profile1);
-  AddProfileToPersonalDataManager(profile2);
-  AddProfileToPersonalDataManager(profile3);
-
-  // Make sure the 3 profiles were saved.
-  EXPECT_EQ(3U, personal_data_->GetProfiles().size());
-
-  base::HistogramTester histogram_tester;
-
-  EXPECT_TRUE(personal_data_->personal_data_manager_cleaner_for_testing()
-                  ->ApplyDedupingRoutineForTesting());
-  WaitForOnPersonalDataChanged();
-
-  // Get the profiles, sorted by ranking to have a deterministic order.
-  std::vector<AutofillProfile*> profiles =
-      personal_data_->GetProfilesToSuggest();
-
-  // Although the profile was verified, the structure of the  street address
-  // still evolved with future observations. In this case, the "." was removed
-  // from a later observation.
-  profile2.SetRawInfoWithVerificationStatus(
-      ADDRESS_HOME_STREET_NAME, u"Evergreen Terrace",
-      structured_address::VerificationStatus::kParsed);
-
-  // |profile1| should have been discarded because the saved profile with the
-  // highest ranking score is verified (|profile2|). Therefore, |profile1|'s
-  // data should not have been merged with |profile2|'s data. Then |profile2|
-  // should have been compared to |profile3| but they should not have merged
-  // because both profiles are verified.
-  ASSERT_EQ(2U, profiles.size());
-  // 3 profiles were considered for dedupe.
-  histogram_tester.ExpectUniqueSample(
-      "Autofill.NumberOfProfilesConsideredForDedupe", 3, 1);
-  // 1 profile was removed (|profile1|).
-  histogram_tester.ExpectUniqueSample(
-      "Autofill.NumberOfProfilesRemovedDuringDedupe", 1, 1);
-
-  EXPECT_EQ(profile2.guid(), profiles[0]->guid());
-  EXPECT_EQ(profile3.guid(), profiles[1]->guid());
-  // The profiles should have kept their original data.
-  EXPECT_TRUE(profile2 == *profiles[0]);
-  EXPECT_TRUE(profile3 == *profiles[1]);
-  EXPECT_EQ(profile2.use_count(), profiles[0]->use_count());
-  EXPECT_EQ(profile3.use_count(), profiles[1]->use_count());
-  EXPECT_EQ(profile2.use_date(), profiles[0]->use_date());
-  EXPECT_EQ(profile3.use_date(), profiles[1]->use_date());
-}
-
-// Tests that ApplyDedupingRoutine works as expected in a realistic scenario.
-// Tests that it merges the diffent set of similar profiles independently and
-// that the resulting profiles have the right values, has no effect on the other
-// profiles and that the data of verified profiles is not modified.
-TEST_F(PersonalDataManagerTest, ApplyDedupingRoutine_MultipleDedupes) {
-  base::test::ScopedFeatureList feature;
-  feature.InitAndEnableFeature(features::kAutofillEnableProfileDeduplication);
-
-  // Create a Homer home profile with a higher ranking score than other Homer
-  // profiles.
-  AutofillProfile Homer1(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&Homer1, "Homer", "J", "Simpson",
-                       "homer.simpson@abc.com", "", "742. Evergreen Terrace",
-                       "", "Springfield", "IL", "91601", "US", "");
-  Homer1.set_use_count(10);
-  Homer1.set_use_date(AutofillClock::Now() - base::Days(1));
-
-  // Create a Homer home profile with a medium ranking score compared to other
-  // Homer profiles.
-  AutofillProfile Homer2(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&Homer2, "Homer", "Jay", "Simpson",
-                       "homer.simpson@abc.com", "", "742 Evergreen Terrace", "",
-                       "Springfield", "IL", "91601", "", "12345678910");
-  Homer2.set_use_count(5);
-  Homer2.set_use_date(AutofillClock::Now() - base::Days(3));
-
-  // Create a Homer home profile with a lower ranking score than other Homer
-  // profiles.
-  AutofillProfile Homer3(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&Homer3, "Homer", "J", "Simpson",
-                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
-                       "", "Springfield", "IL", "91601", "", "");
-  Homer3.set_use_count(3);
-  Homer3.set_use_date(AutofillClock::Now() - base::Days(5));
-
-  // Create a Homer work profile (different address).
-  AutofillProfile Homer4(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&Homer4, "Homer", "J", "Simpson",
-                       "homer.simpson@abc.com", "Fox", "12 Nuclear Plant.", "",
-                       "Springfield", "IL", "91601", "US", "9876543");
-  Homer4.set_use_count(3);
-  Homer4.set_use_date(AutofillClock::Now() - base::Days(5));
-
-  // Create a Marge profile with a lower ranking score that other Marge
-  // profiles.
-  AutofillProfile Marge1(base::GenerateGUID(), kSettingsOrigin);
-  test::SetProfileInfo(&Marge1, "Marjorie", "J", "Simpson",
-                       "marge.simpson@abc.com", "", "742 Evergreen Terrace", "",
-                       "Springfield", "IL", "91601", "", "12345678910");
-  Marge1.set_use_count(4);
-  Marge1.set_use_date(AutofillClock::Now() - base::Days(3));
-
-  // Create a verified Marge home profile with a lower ranking score that the
-  // other Marge profile.
-  AutofillProfile Marge2(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&Marge2, "Marjorie", "Jacqueline", "Simpson",
-                       "marge.simpson@abc.com", "", "742 Evergreen Terrace", "",
-                       "Springfield", "IL", "91601", "", "12345678910");
-  Marge2.set_use_count(2);
-  Marge2.set_use_date(AutofillClock::Now() - base::Days(3));
-
-  // Create a Barney profile (guest user).
-  AutofillProfile Barney(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&Barney, "Barney", "", "Gumble", "barney.gumble@abc.com",
-                       "ABC", "123 Other Street", "", "Springfield", "IL",
-                       "91601", "", "");
-  Barney.set_use_count(1);
-  Barney.set_use_date(AutofillClock::Now() - base::Days(180));
-  Barney.FinalizeAfterImport();
-
-  AddProfileToPersonalDataManager(Homer1);
-  AddProfileToPersonalDataManager(Homer2);
-  AddProfileToPersonalDataManager(Homer3);
-  AddProfileToPersonalDataManager(Homer4);
-  AddProfileToPersonalDataManager(Marge1);
-  AddProfileToPersonalDataManager(Marge2);
-  AddProfileToPersonalDataManager(Barney);
-
-  // Make sure the 7 profiles were saved;
-  EXPECT_EQ(7U, personal_data_->GetProfiles().size());
-
-  base::HistogramTester histogram_tester;
-
-  // |Homer1| should get merged into |Homer2| which should then be merged into
-  // |Homer3|. |Marge2| should be discarded in favor of |Marge1| which is
-  // verified. |Homer4| and |Barney| should not be deduped at all.
-  EXPECT_TRUE(personal_data_->personal_data_manager_cleaner_for_testing()
-                  ->ApplyDedupingRoutineForTesting());
-  WaitForOnPersonalDataChanged();
-
-  // Get the profiles, sorted by ranking score to have a deterministic order.
-  std::vector<AutofillProfile*> profiles =
-      personal_data_->GetProfilesToSuggest();
-
-  // The 2 duplicates Homer home profiles with the higher ranking score and the
-  // unverified Marge profile should have been deduped.
-  ASSERT_EQ(4U, profiles.size());
-  // 7 profiles were considered for dedupe.
-  histogram_tester.ExpectUniqueSample(
-      "Autofill.NumberOfProfilesConsideredForDedupe", 7, 1);
-  // 3 profile were removed (|Homer1|, |Homer2| and |Marge2|).
-  histogram_tester.ExpectUniqueSample(
-      "Autofill.NumberOfProfilesRemovedDuringDedupe", 3, 1);
-
-  // The remaining profiles should be |Homer3|, |Marge1|, |Homer4| and |Barney|
-  // in this order of ranking score.
-  EXPECT_EQ(Homer3.guid(), profiles[0]->guid());
-  EXPECT_EQ(Marge1.guid(), profiles[1]->guid());
-  EXPECT_EQ(Homer4.guid(), profiles[2]->guid());
-  EXPECT_EQ(Barney.guid(), profiles[3]->guid());
-
-  // |Homer3|'s data:
-  // The address should be saved with the syntax of |Homer1| since it has the
-  // highest ranking score.
-  EXPECT_EQ(u"742. Evergreen Terrace",
-            profiles[0]->GetRawInfo(ADDRESS_HOME_LINE1));
-  // The middle name should be the full version found in |Homer2|,
-  EXPECT_EQ(u"Jay", profiles[0]->GetRawInfo(NAME_MIDDLE));
-  // The phone number from |Homer2| should be kept (no loss of information).
-  EXPECT_EQ(u"12345678910", profiles[0]->GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
-  // The company name from |Homer3| should be kept (no loss of information).
-  EXPECT_EQ(u"Fox", profiles[0]->GetRawInfo(COMPANY_NAME));
-  // The country from |Homer1| profile should be kept (no loss of information).
-  EXPECT_EQ(u"US", profiles[0]->GetRawInfo(ADDRESS_HOME_COUNTRY));
-  // The use count that results from the merge should be the max of Homer 1, 2
-  // and 3's respective use counts.
-  EXPECT_EQ(10U, profiles[0]->use_count());
-  // The use date that results from the merge should be the one from the
-  // |Homer1| since it was the most recently used profile.
-  EXPECT_LT(Homer1.use_date() - base::Seconds(5), profiles[0]->use_date());
-  EXPECT_GT(Homer1.use_date() + base::Seconds(5), profiles[0]->use_date());
-
-  // The other profiles should not have been modified.
-  EXPECT_TRUE(Marge1 == *profiles[1]);
-  EXPECT_TRUE(Homer4 == *profiles[2]);
-  EXPECT_TRUE(Barney == *profiles[3]);
-}
-
-TEST_F(PersonalDataManagerTest, ApplyDedupingRoutine_NopIfZeroProfiles) {
-  base::test::ScopedFeatureList feature;
-  feature.InitAndEnableFeature(features::kAutofillEnableProfileDeduplication);
-  EXPECT_TRUE(personal_data_->GetProfiles().empty());
-  EXPECT_FALSE(personal_data_->personal_data_manager_cleaner_for_testing()
-                   ->ApplyDedupingRoutineForTesting());
-}
-
-TEST_F(PersonalDataManagerTest, ApplyDedupingRoutine_NopIfOneProfile) {
-  base::test::ScopedFeatureList feature;
-  feature.InitAndEnableFeature(features::kAutofillEnableProfileDeduplication);
-
-  // Create a profile to dedupe.
-  AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile, "Homer", "J", "Simpson",
-                       "homer.simpson@abc.com", "", "742. Evergreen Terrace",
-                       "", "Springfield", "IL", "91601", "US", "");
-
-  AddProfileToPersonalDataManager(profile);
-
-  EXPECT_EQ(1U, personal_data_->GetProfiles().size());
-  EXPECT_FALSE(personal_data_->personal_data_manager_cleaner_for_testing()
-                   ->ApplyDedupingRoutineForTesting());
-}
-
-// Tests that ApplyDedupingRoutine is not run a second time on the same major
-// version.
-TEST_F(PersonalDataManagerTest, ApplyDedupingRoutine_OncePerVersion) {
-  base::test::ScopedFeatureList feature;
-  feature.InitAndEnableFeature(features::kAutofillEnableProfileDeduplication);
-
-  // Create a profile to dedupe.
-  AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile1, "Homer", "J", "Simpson",
-                       "homer.simpson@abc.com", "", "742. Evergreen Terrace",
-                       "", "Springfield", "IL", "91601", "US", "");
-
-  // Create a similar profile.
-  AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile2, "Homer", "J", "Simpson",
-                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
-                       "", "Springfield", "IL", "91601", "", "");
-
-  AddProfileToPersonalDataManager(profile1);
-  AddProfileToPersonalDataManager(profile2);
-
-  EXPECT_EQ(2U, personal_data_->GetProfiles().size());
-
-  // The deduping routine should be run a first time.
-  EXPECT_TRUE(personal_data_->personal_data_manager_cleaner_for_testing()
-                  ->ApplyDedupingRoutineForTesting());
-  WaitForOnPersonalDataChanged();
-
-  std::vector<AutofillProfile*> profiles = personal_data_->GetProfiles();
-
-  // The profiles should have been deduped
-  EXPECT_EQ(1U, profiles.size());
-
-  // Add another duplicate profile.
-  AutofillProfile profile3(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile3, "Homer", "J", "Simpson",
-                       "homer.simpson@abc.com", "Fox", "742 Evergreen Terrace.",
-                       "", "Springfield", "IL", "91601", "", "");
-
-  AddProfileToPersonalDataManager(profile3);
-
-  // Make sure |profile3| was saved.
-  EXPECT_EQ(2U, personal_data_->GetProfiles().size());
-
-  // The deduping routine should not be run.
-  EXPECT_FALSE(personal_data_->personal_data_manager_cleaner_for_testing()
-                   ->ApplyDedupingRoutineForTesting());
-
-  // The two duplicate profiles should still be present.
-  EXPECT_EQ(2U, personal_data_->GetProfiles().size());
-}
-
-// Tests that settings-inaccessible profile values are removed from every stored
-// profile on startup.
-TEST_F(PersonalDataManagerTest, RemoveInaccessibleProfileValuesOnStartup) {
-  base::test::ScopedFeatureList feature;
-  feature.InitAndEnableFeatureWithParameters(
-      features::kAutofillRemoveInaccessibleProfileValues,
-      {{features::kAutofillRemoveInaccessibleProfileValuesOnStartup.name,
-        "true"}});
-
-  // Add a German and a US profile.
-  AutofillProfile profile0(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile0, "Marion", "Mitchell", "Morrison",
-                       "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5",
-                       "Hollywood", "CA", "91601", "DE", "12345678910");
-  AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile1, "Josephine", "Alicia", "Saenz",
-                       "joewayne@me.xyz", "Fox", "903 Apple Ct.", nullptr,
-                       "Orlando", "FL", "32801", "US", "19482937549");
-  AddProfileToPersonalDataManager(profile0);
-  AddProfileToPersonalDataManager(profile1);
-
-  personal_data_->personal_data_manager_cleaner_for_testing()
-      ->RemoveInaccessibleProfileValuesForTesting();
-  WaitForOnPersonalDataChanged();
-
-  // profile0 should have it's state removed, while the US profile should remain
-  // unchanged.
-  profile0.SetRawInfo(ADDRESS_HOME_STATE, u"");
-  ExpectSameElements({&profile0, &profile1}, personal_data_->GetProfiles());
-}
-
-// Tests that DeleteDisusedAddresses only deletes the addresses that are
-// supposed to be deleted.
-TEST_F(PersonalDataManagerTest,
-       DeleteDisusedAddresses_DeleteDesiredAddressesOnly) {
-  auto now = AutofillClock::Now();
-
-  // Create unverified/disused/not-used-by-valid-credit-card
-  // address(deletable).
-  AutofillProfile profile0(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile0, "Alice", "", "Delete", "", "ACME",
-                       "1234 Evergreen Terrace", "Bld. 6", "Springfield", "IL",
-                       "32801", "US", "15151231234");
-  profile0.set_use_date(now - base::Days(400));
-  AddProfileToPersonalDataManager(profile0);
-
-  // Create unverified/disused/used-by-expired-credit-card address(deletable).
-  AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile1, "Bob", "", "Delete", "", "ACME",
-                       "1234 Evergreen Terrace", "Bld. 7", "Springfield", "IL",
-                       "32801", "US", "15151231234");
-  profile1.set_use_date(now - base::Days(400));
-  CreditCard credit_card0(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetCreditCardInfo(&credit_card0, "Bob",
-                          "5105105105105100" /* Mastercard */, "04", "1999",
-                          "1");
-  credit_card0.set_use_date(now - base::Days(400));
-  credit_card0.set_billing_address_id(profile1.guid());
-  AddProfileToPersonalDataManager(profile1);
-  personal_data_->AddCreditCard(credit_card0);
-  WaitForOnPersonalDataChanged();
-  // Create verified/disused/not-used-by-valid-credit-card address(not
-  // deletable).
-  AutofillProfile profile2(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile2, "Charlie", "", "Keep", "", "ACME",
-                       "1234 Evergreen Terrace", "Bld. 8", "Springfield", "IL",
-                       "32801", "US", "15151231234");
-  profile2.set_origin(kSettingsOrigin);
-  profile2.set_use_date(now - base::Days(400));
-  AddProfileToPersonalDataManager(profile2);
-
-  // Create unverified/recently-used/not-used-by-valid-credit-card address(not
-  // deletable).
-  AutofillProfile profile3(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile3, "Dave", "", "Keep", "", "ACME",
-                       "1234 Evergreen Terrace", "Bld. 9", "Springfield", "IL",
-                       "32801", "US", "15151231234");
-  profile3.set_use_date(now - base::Days(4));
-  AddProfileToPersonalDataManager(profile3);
-
-  // Create unverified/disused/used-by-valid-credit-card address(not deletable).
-  AutofillProfile profile4(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile4, "Emma", "", "Keep", "", "ACME",
-                       "1234 Evergreen Terrace", "Bld. 10", "Springfield", "IL",
-                       "32801", "US", "15151231234");
-  profile4.set_use_date(now - base::Days(400));
-  CreditCard credit_card1(CreditCard::MASKED_SERVER_CARD, "c987");
-  test::SetCreditCardInfo(&credit_card1, "Emma", "6543", "01", "2999", "1");
-  credit_card1.SetNetworkForMaskedCard(kVisaCard);
-  credit_card1.set_billing_address_id(profile4.guid());
-  credit_card1.set_use_date(now - base::Days(1));
-  AddProfileToPersonalDataManager(profile4);
-  personal_data_->AddCreditCard(credit_card1);
-
-  WaitForOnPersonalDataChanged();
-
-  EXPECT_EQ(5U, personal_data_->GetProfiles().size());
-  EXPECT_EQ(2U, personal_data_->GetCreditCards().size());
-
-  // DeleteDisusedAddresses should return true.
-  EXPECT_TRUE(personal_data_->personal_data_manager_cleaner_for_testing()
-                  ->DeleteDisusedAddressesForTesting());
-  WaitForOnPersonalDataChanged();
-
-  EXPECT_EQ(3U, personal_data_->GetProfiles().size());
-  EXPECT_EQ(2U, personal_data_->GetCreditCards().size());
-  EXPECT_EQ(u"Keep", personal_data_->GetProfiles()[0]->GetRawInfo(NAME_LAST));
-  EXPECT_EQ(u"Keep", personal_data_->GetProfiles()[1]->GetRawInfo(NAME_LAST));
-  EXPECT_EQ(u"Keep", personal_data_->GetProfiles()[2]->GetRawInfo(NAME_LAST));
-}
-
-// Tests that DeleteDisusedCreditCards deletes desired credit cards only.
-TEST_F(PersonalDataManagerTest,
-       DeleteDisusedCreditCards_OnlyDeleteExpiredDisusedLocalCards) {
-  const char kHistogramName[] = "Autofill.CreditCardsDeletedForDisuse";
-  auto now = AutofillClock::Now();
-
-  // Create a recently used local card, it is expected to remain.
-  CreditCard credit_card1(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetCreditCardInfo(&credit_card1, "Alice",
-                          "378282246310005" /* American Express */, "04",
-                          "2999", "1");
-  credit_card1.set_use_date(now - base::Days(4));
-
-  // Create a local card that was expired 400 days ago, but recently used.
-  // It is expected to remain.
-  CreditCard credit_card2(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetCreditCardInfo(&credit_card2, "Bob",
-                          "378282246310006" /* American Express */, "04",
-                          "1999", "1");
-  credit_card2.set_use_date(now - base::Days(4));
-
-  // Create a local card expired recently, and last used 400 days ago.
-  // It is expected to remain.
-  CreditCard credit_card3(base::GenerateGUID(), test::kEmptyOrigin);
-  base::Time expiry_date = now - base::Days(32);
-  base::Time::Exploded exploded;
-  expiry_date.UTCExplode(&exploded);
-  test::SetCreditCardInfo(&credit_card3, "Clyde", "4111111111111111" /* Visa */,
-                          base::StringPrintf("%02d", exploded.month).c_str(),
-                          base::StringPrintf("%04d", exploded.year).c_str(),
-                          "1");
-  credit_card3.set_use_date(now - base::Days(400));
-
-  // Create a local card expired 400 days ago, and last used 400 days ago.
-  // It is expected to be deleted.
-  CreditCard credit_card4(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetCreditCardInfo(&credit_card4, "David",
-                          "5105105105105100" /* Mastercard */, "04", "1999",
-                          "1");
-  credit_card4.set_use_date(now - base::Days(400));
-  personal_data_->AddCreditCard(credit_card1);
-  personal_data_->AddCreditCard(credit_card2);
-  personal_data_->AddCreditCard(credit_card3);
-  personal_data_->AddCreditCard(credit_card4);
-
-  // Create a unmasked server card expired 400 days ago, and last used 400
-  // days ago.
-  // It is expected to remain because we do not delete server cards.
-  CreditCard credit_card5(CreditCard::FULL_SERVER_CARD, "c789");
-  test::SetCreditCardInfo(&credit_card5, "Emma", "4234567890123456" /* Visa */,
-                          "04", "1999", "1");
-  credit_card5.set_use_date(now - base::Days(400));
-
-  // Create masked server card expired 400 days ago, and last used 400 days ago.
-  // It is expected to remain because we do not delete server cards.
-  CreditCard credit_card6(CreditCard::MASKED_SERVER_CARD, "c987");
-  test::SetCreditCardInfo(&credit_card6, "Frank", "6543", "01", "1998", "1");
-  credit_card6.set_use_date(now - base::Days(400));
-  credit_card6.SetNetworkForMaskedCard(kVisaCard);
-
-  // Save the server cards and set used_date to desired dates.
-  std::vector<CreditCard> server_cards;
-  server_cards.push_back(credit_card5);
-  server_cards.push_back(credit_card6);
-  SetServerCards(server_cards);
-  personal_data_->UpdateServerCardsMetadata({credit_card5, credit_card6});
-
-  WaitForOnPersonalDataChanged();
-  EXPECT_EQ(6U, personal_data_->GetCreditCards().size());
-
-  // Setup histograms capturing.
-  base::HistogramTester histogram_tester;
-
-  // DeleteDisusedCreditCards should return true to indicate it was run.
-  EXPECT_TRUE(personal_data_->personal_data_manager_cleaner_for_testing()
-                  ->DeleteDisusedCreditCardsForTesting());
-
-  // Wait for the data to be refreshed.
-  WaitForOnPersonalDataChanged();
-
-  EXPECT_EQ(5U, personal_data_->GetCreditCards().size());
-  std::unordered_set<std::u16string> expectedToRemain = {
-      u"Alice", u"Bob", u"Clyde", u"Emma", u"Frank"};
-  for (auto* card : personal_data_->GetCreditCards()) {
-    EXPECT_NE(expectedToRemain.end(),
-              expectedToRemain.find(card->GetRawInfo(CREDIT_CARD_NAME_FULL)));
-  }
-
-  // Verify histograms are logged.
-  histogram_tester.ExpectTotalCount(kHistogramName, 1);
-  histogram_tester.ExpectBucketCount(kHistogramName, 1, 1);
-}
-
 TEST_F(PersonalDataManagerTest, DeleteLocalCreditCards) {
   CreditCard credit_card1(base::GenerateGUID(), test::kEmptyOrigin);
   test::SetCreditCardInfo(&credit_card1, "Alice",
@@ -5948,120 +4864,6 @@
 #endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) ||
         // BUILDFLAG(IS_CHROMEOS)
 
-// Tests that all the non settings origins of autofill profiles are cleared but
-// that the settings origins are untouched.
-TEST_F(PersonalDataManagerTest, ClearProfileNonSettingsOrigins) {
-  // Create three profile with a nonsettings, non-empty origin.
-  AutofillProfile profile0(base::GenerateGUID(), "https://www.example.com");
-  test::SetProfileInfo(&profile0, "Marion0", "Mitchell", "Morrison",
-                       "johnwayne@me.xyz", "Fox",
-                       "123 Zoo St.\nSecond Line\nThird line", "unit 5",
-                       "Hollywood", "CA", "91601", "US", "12345678910");
-  profile0.set_use_count(10000);
-  AddProfileToPersonalDataManager(profile0);
-
-  AutofillProfile profile1(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetProfileInfo(&profile1, "Marion1", "Mitchell", "Morrison",
-                       "johnwayne@me.xyz", "Fox",
-                       "123 Zoo St.\nSecond Line\nThird line", "unit 5",
-                       "Hollywood", "CA", "91601", "US", "12345678910");
-  profile1.set_use_count(1000);
-  AddProfileToPersonalDataManager(profile1);
-
-  AutofillProfile profile2(base::GenerateGUID(), "1234");
-  test::SetProfileInfo(&profile2, "Marion2", "Mitchell", "Morrison",
-                       "johnwayne@me.xyz", "Fox",
-                       "123 Zoo St.\nSecond Line\nThird line", "unit 5",
-                       "Hollywood", "CA", "91601", "US", "12345678910");
-  profile2.set_use_count(100);
-  AddProfileToPersonalDataManager(profile2);
-
-  // Create a profile with a settings origin.
-  AutofillProfile profile3(base::GenerateGUID(), kSettingsOrigin);
-  test::SetProfileInfo(&profile3, "Marion3", "Mitchell", "Morrison",
-                       "johnwayne@me.xyz", "Fox",
-                       "123 Zoo St.\nSecond Line\nThird line", "unit 5",
-                       "Hollywood", "CA", "91601", "US", "12345678910");
-  profile3.set_use_count(10);
-  AddProfileToPersonalDataManager(profile3);
-
-  ASSERT_EQ(4U, personal_data_->GetProfiles().size());
-
-  base::RunLoop run_loop;
-  EXPECT_CALL(personal_data_observer_, OnPersonalDataFinishedProfileTasks())
-      .WillRepeatedly(QuitMessageLoop(&run_loop));
-  EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged())
-      .Times(2);  // The setting of profiles 0 and 2 will be cleared.
-
-  personal_data_->personal_data_manager_cleaner_for_testing()
-      ->ClearProfileNonSettingsOriginsForTesting();
-  run_loop.Run();
-
-  ASSERT_EQ(4U, personal_data_->GetProfiles().size());
-
-  // The first three profiles' origin should be cleared and the fourth one still
-  // be the settings origin.
-  EXPECT_TRUE(personal_data_->GetProfilesToSuggest()[0]->origin().empty());
-  EXPECT_TRUE(personal_data_->GetProfilesToSuggest()[1]->origin().empty());
-  EXPECT_TRUE(personal_data_->GetProfilesToSuggest()[2]->origin().empty());
-  EXPECT_EQ(kSettingsOrigin,
-            personal_data_->GetProfilesToSuggest()[3]->origin());
-}
-
-// Tests that all the non settings origins of autofill credit cards are cleared
-// but that the settings origins are untouched.
-TEST_F(PersonalDataManagerTest, ClearCreditCardNonSettingsOrigins) {
-  // Create three cards with a non settings origin.
-  CreditCard credit_card0(base::GenerateGUID(), "https://www.example.com");
-  test::SetCreditCardInfo(&credit_card0, "Bob0",
-                          "5105105105105100" /* Mastercard */, "04", "1999",
-                          "1");
-  credit_card0.set_use_count(10000);
-  personal_data_->AddCreditCard(credit_card0);
-
-  CreditCard credit_card1(base::GenerateGUID(), test::kEmptyOrigin);
-  test::SetCreditCardInfo(&credit_card1, "Bob1",
-                          "5105105105105101" /* Mastercard */, "04", "1999",
-                          "1");
-  credit_card1.set_use_count(1000);
-  personal_data_->AddCreditCard(credit_card1);
-
-  CreditCard credit_card2(base::GenerateGUID(), "1234");
-  test::SetCreditCardInfo(&credit_card2, "Bob2",
-                          "5105105105105102" /* Mastercard */, "04", "1999",
-                          "1");
-  credit_card2.set_use_count(100);
-  personal_data_->AddCreditCard(credit_card2);
-
-  // Create a card with a settings origin.
-  CreditCard credit_card3(base::GenerateGUID(), kSettingsOrigin);
-  test::SetCreditCardInfo(&credit_card3, "Bob3",
-                          "5105105105105103" /* Mastercard */, "04", "1999",
-                          "1");
-  credit_card3.set_use_count(10);
-  personal_data_->AddCreditCard(credit_card3);
-
-  WaitForOnPersonalDataChanged();
-  ASSERT_EQ(4U, personal_data_->GetCreditCards().size());
-
-  personal_data_->personal_data_manager_cleaner_for_testing()
-      ->ClearCreditCardNonSettingsOriginsForTesting();
-
-  WaitForOnPersonalDataChanged();
-  ASSERT_EQ(4U, personal_data_->GetCreditCards().size());
-
-  // The first three profiles' origin should be cleared and the fourth one still
-  // be the settings origin.
-  EXPECT_TRUE(
-      personal_data_->GetCreditCardsToSuggest(false)[0]->origin().empty());
-  EXPECT_TRUE(
-      personal_data_->GetCreditCardsToSuggest(false)[1]->origin().empty());
-  EXPECT_TRUE(
-      personal_data_->GetCreditCardsToSuggest(false)[2]->origin().empty());
-  EXPECT_EQ(kSettingsOrigin,
-            personal_data_->GetCreditCardsToSuggest(false)[3]->origin());
-}
-
 // Tests that all the non settings origins of autofill profiles are cleared even
 // if sync is disabled.
 TEST_F(
diff --git a/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl_unittest.cc b/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl_unittest.cc
index 0cd137c..a14f7f01 100644
--- a/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl_unittest.cc
+++ b/components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl_unittest.cc
@@ -279,55 +279,13 @@
 TEST_F(CardUnmaskPromptControllerImplTest, DisplayCardInformation) {
   ShowPrompt();
 #if BUILDFLAG(IS_IOS)
-  EXPECT_TRUE(base::UTF16ToUTF8(controller_->GetInstructionsMessage())
-                  .find("Mastercard  " + test::ObfuscatedCardDigitsAsUTF8(
-                                             "2109")) != std::string::npos);
-#else
-  EXPECT_TRUE(base::UTF16ToUTF8(controller_->GetWindowTitle())
-                  .find("Mastercard  " + test::ObfuscatedCardDigitsAsUTF8(
-                                             "2109")) != std::string::npos);
-#endif
-}
-
-// Ensures to fallback to network name in the instruction message on iOS and in
-// the title on other platforms when the nickname is invalid.
-TEST_F(CardUnmaskPromptControllerImplTest, Nickname_NicknameInvalid) {
-  SetCreditCardForTesting(test::GetMaskedServerCardWithInvalidNickname());
-  ShowPrompt();
-#if BUILDFLAG(IS_IOS)
-  EXPECT_TRUE(
-      base::UTF16ToUTF8(controller_->GetInstructionsMessage()).find("Visa") !=
-      std::string::npos);
-  EXPECT_FALSE(base::UTF16ToUTF8(controller_->GetInstructionsMessage())
-                   .find("Invalid nickname which is too long") !=
-               std::string::npos);
-#else
-  EXPECT_TRUE(base::UTF16ToUTF8(controller_->GetWindowTitle()).find("Visa") !=
+  EXPECT_TRUE(controller_->GetInstructionsMessage().find(
+                  card_.CardIdentifierStringForAutofillDisplay()) !=
               std::string::npos);
-  EXPECT_FALSE(base::UTF16ToUTF8(controller_->GetWindowTitle())
-                   .find("Invalid nickname which is too long") !=
-               std::string::npos);
-#endif
-}
-
-// Ensures the nickname is displayed (instead of network) in the instruction
-// message on iOS and in the title on other platforms when the nickname is
-// valid.
-TEST_F(CardUnmaskPromptControllerImplTest, Nickname_NicknameValid) {
-  SetCreditCardForTesting(test::GetMaskedServerCardWithNickname());
-  ShowPrompt();
-#if BUILDFLAG(IS_IOS)
-  EXPECT_FALSE(
-      base::UTF16ToUTF8(controller_->GetInstructionsMessage()).find("Visa") !=
-      std::string::npos);
-  EXPECT_TRUE(base::UTF16ToUTF8(controller_->GetInstructionsMessage())
-                  .find("Test nickname") != std::string::npos);
 #else
-  EXPECT_FALSE(base::UTF16ToUTF8(controller_->GetWindowTitle()).find("Visa") !=
-               std::string::npos);
-  EXPECT_TRUE(
-      base::UTF16ToUTF8(controller_->GetWindowTitle()).find("Test nickname") !=
-      std::string::npos);
+  EXPECT_TRUE(controller_->GetWindowTitle().find(
+                  card_.CardIdentifierStringForAutofillDisplay()) !=
+              std::string::npos);
 #endif
 }
 
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc
index 99862bf..d3d18bde 100644
--- a/components/autofill/core/common/autofill_features.cc
+++ b/components/autofill/core/common/autofill_features.cc
@@ -216,7 +216,7 @@
 
 // Controls whether to save the first number in a form with multiple phone
 // numbers instead of aborting the import.
-// TODO(crbug.com/1167484) Remove once launched
+// TODO(crbug.com/1167484) Remove once launched.
 const base::Feature kAutofillEnableImportWhenMultiplePhoneNumbers{
     "AutofillEnableImportWhenMultiplePhoneNumbers",
     base::FEATURE_DISABLED_BY_DEFAULT};
@@ -352,6 +352,12 @@
     "AutofillIgnoreUnmappableAutocompleteValues",
     base::FEATURE_DISABLED_BY_DEFAULT};
 
+// When enabled, <label for=..> inference relies on control.labels() instead of
+// iterating through all <label> tags manually.
+// TODO(crbug.com/1339277) Remove once launched.
+const base::Feature kAutofillImprovedLabelForInference{
+    "AutofillImprovedLabelForInference", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // When enabled, only changed values are highlighted in preview mode.
 // TODO(crbug/1248585): Remove when launched.
 const base::Feature kAutofillHighlightOnlyChangedValuesInPreviewMode{
@@ -435,6 +441,12 @@
 const base::Feature kAutofillParseAsync{"AutofillParseAsync",
                                         base::FEATURE_DISABLED_BY_DEFAULT};
 
+// If enabled, local heuristics fall back to interpreting the fields' name as an
+// autocomplete type.
+// TODO(crbug.com/TODO) Remove once launched.
+const base::Feature kAutofillParseNameAsAutocompleteType{
+    "AutofillParseNameAsAutocompleteType", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // If the feature is enabled, FormTracker's probable-form-submission detection
 // is disabled and replaced with browser-side detection.
 // TODO(crbug/1117451): Remove once it works.
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h
index 64d2eb52..a577fef 100644
--- a/components/autofill/core/common/autofill_features.h
+++ b/components/autofill/core/common/autofill_features.h
@@ -133,6 +133,8 @@
 COMPONENT_EXPORT(AUTOFILL)
 extern const base::Feature kAutofillIgnoreUnmappableAutocompleteValues;
 COMPONENT_EXPORT(AUTOFILL)
+extern const base::Feature kAutofillImprovedLabelForInference;
+COMPONENT_EXPORT(AUTOFILL)
 extern const base::Feature kAutofillHighlightOnlyChangedValuesInPreviewMode;
 COMPONENT_EXPORT(AUTOFILL)
 extern const base::Feature kAutofillServerTypeTakesPrecedence;
@@ -153,6 +155,8 @@
 COMPONENT_EXPORT(AUTOFILL)
 extern const base::Feature kAutofillParseAsync;
 COMPONENT_EXPORT(AUTOFILL)
+extern const base::Feature kAutofillParseNameAsAutocompleteType;
+COMPONENT_EXPORT(AUTOFILL)
 extern const base::Feature kAutofillParsingPatternProvider;
 COMPONENT_EXPORT(AUTOFILL)
 extern const base::FeatureParam<std::string>
diff --git a/components/autofill/core/common/form_field_data.cc b/components/autofill/core/common/form_field_data.cc
index 29e3b27..d99449d 100644
--- a/components/autofill/core/common/form_field_data.cc
+++ b/components/autofill/core/common/form_field_data.cc
@@ -250,6 +250,20 @@
 Section::Section(const Section& section) = default;
 Section::~Section() = default;
 
+bool operator==(const Section::Autocomplete& a,
+                const Section::Autocomplete& b) {
+  return std::tie(a.section, a.mode) == std::tie(b.section, b.mode);
+}
+
+bool operator!=(const Section::Autocomplete& a,
+                const Section::Autocomplete& b) {
+  return !(a == b);
+}
+
+bool operator<(const Section::Autocomplete& a, const Section::Autocomplete& b) {
+  return std::tie(a.section, a.mode) < std::tie(b.section, b.mode);
+}
+
 bool operator==(const Section::FieldIdentifier& a,
                 const Section::FieldIdentifier& b) {
   return std::tie(a.field_name, a.local_frame_id, a.field_renderer_id) ==
@@ -293,20 +307,10 @@
   prefix_ = CreditCard();
 }
 
-bool Section::SetPrefixFromAutocomplete(
-    const Autocomplete& autocomplete_section,
-    HtmlFieldMode autocomplete_mode) {
-  if (autocomplete_section.empty() && autocomplete_mode == HTML_MODE_NONE)
+bool Section::SetPrefixFromAutocomplete(Autocomplete autocomplete) {
+  if (autocomplete.section.empty() && autocomplete.mode == HTML_MODE_NONE)
     return false;
-  // To prevent potential section name collisions, append `kDefaultSection`
-  // suffix to fields without a `HtmlFieldMode`. Without this, 'autocomplete'
-  // attribute values "section--shipping street-address" and "shipping
-  // street-address" would result in the same `prefix_`.
-  prefix_ =
-      autocomplete_section +
-      (autocomplete_mode != HTML_MODE_NONE
-           ? "-" + std::string(HtmlFieldModeToStringPiece(autocomplete_mode))
-           : kDefaultSection);
+  prefix_ = std::move(autocomplete);
   return true;
 }
 
@@ -322,9 +326,16 @@
 
 std::string Section::ToString() const {
   std::string section_name;
-  if (const Autocomplete* autocomplete_section =
-          absl::get_if<Autocomplete>(&prefix_)) {
-    section_name = *autocomplete_section;
+  if (const Autocomplete* autocomplete = absl::get_if<Autocomplete>(&prefix_)) {
+    // To prevent potential section name collisions, append `kDefaultSection`
+    // suffix to fields without a `HtmlFieldMode`. Without this, 'autocomplete'
+    // attribute values "section--shipping street-address" and "shipping
+    // street-address" would have the same prefix.
+    section_name =
+        autocomplete->section +
+        (autocomplete->mode != HTML_MODE_NONE
+             ? "-" + std::string(HtmlFieldModeToStringPiece(autocomplete->mode))
+             : kDefaultSection);
   } else if (const FieldIdentifier* f =
                  absl::get_if<FieldIdentifier>(&prefix_)) {
     FieldIdentifier field_identifier = *f;
diff --git a/components/autofill/core/common/form_field_data.h b/components/autofill/core/common/form_field_data.h
index caa7750..8214c43 100644
--- a/components/autofill/core/common/form_field_data.h
+++ b/components/autofill/core/common/form_field_data.h
@@ -71,7 +71,11 @@
   // added to the legacy section string based on the field type group.
   enum class FieldTypeGroupSuffix : uint8_t { kNoGroup, kDefault, kCreditCard };
 
-  using Autocomplete = std::string;
+  struct Autocomplete {
+    std::string section;
+    HtmlFieldMode mode;
+  };
+
   using Default = base::StrongAlias<struct DefaultTag, absl::monostate>;
 
   // TODO(crbug.com/1153539): Remove when sectioning is redesigned.
@@ -79,7 +83,6 @@
 
   struct FieldIdentifier {
     FieldIdentifier() = default;
-
     FieldIdentifier(std::string field_name,
                     size_t local_frame_id,
                     FieldRendererId field_renderer_id)
@@ -123,8 +126,7 @@
 
   void set_field_type_group(FieldTypeGroupSuffix field_type_group);
   void SetPrefixToCreditCard();
-  bool SetPrefixFromAutocomplete(const Autocomplete& autocomplete_section,
-                                 HtmlFieldMode autocomplete_mode);
+  bool SetPrefixFromAutocomplete(Autocomplete autocomplete);
 
   // Sets the section prefix based on the field identifiers: the field's name,
   // mapped frame id, renderer id. We do not use LocalFrameTokens but instead
diff --git a/components/autofill/core/common/html_field_types.h b/components/autofill/core/common/html_field_types.h
index 8c61822..c3a7c31 100644
--- a/components/autofill/core/common/html_field_types.h
+++ b/components/autofill/core/common/html_field_types.h
@@ -5,6 +5,7 @@
 #ifndef COMPONENTS_AUTOFILL_CORE_COMMON_HTML_FIELD_TYPES_H_
 #define COMPONENTS_AUTOFILL_CORE_COMMON_HTML_FIELD_TYPES_H_
 
+#include <stdint.h>
 #include "base/strings/string_piece_forward.h"
 
 namespace autofill {
@@ -96,7 +97,7 @@
 
 // The list of all HTML autocomplete field mode hints supported by Chrome.
 // See [ http://is.gd/whatwg_autocomplete ] for the full list of specced hints.
-enum HtmlFieldMode {
+enum HtmlFieldMode : uint8_t {
   HTML_MODE_NONE,
   HTML_MODE_BILLING,
   HTML_MODE_SHIPPING,
diff --git a/components/autofill/core/common/mojom/autofill_types.mojom b/components/autofill/core/common/mojom/autofill_types.mojom
index e9c9b94d..0afc2f8c 100644
--- a/components/autofill/core/common/mojom/autofill_types.mojom
+++ b/components/autofill/core/common/mojom/autofill_types.mojom
@@ -137,6 +137,14 @@
   mojo_base.mojom.String16 content;
 };
 
+// autofill::Section::Autocomplete
+// (components/autofill/core/common/form_field_data.h)
+struct SectionAutocomplete {
+  string section;
+  // autofill::HtmlFieldMode
+  uint8 html_field_mode;
+};
+
 // autofill::Section::FieldIdentifier
 // (components/autofill/core/common/form_field_data.h)
 struct SectionFieldIdentifier {
@@ -149,7 +157,7 @@
 // (components/autofill/core/common/form_field_data.h)
 union SectionPrefix {
   bool default_prefix;
-  string autocomplete_section_prefix;
+  SectionAutocomplete autocomplete_section_prefix;
   SectionFieldIdentifier from_field_prefix;
   bool credit_card_prefix;
 };
diff --git a/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc b/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc
index 70ba4286..1e41d15 100644
--- a/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc
+++ b/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc
@@ -6,6 +6,7 @@
 
 #include "base/i18n/rtl.h"
 #include "components/autofill/core/common/form_field_data.h"
+#include "components/autofill/core/common/html_field_types.h"
 #include "mojo/public/cpp/base/string16_mojom_traits.h"
 #include "mojo/public/cpp/base/time_mojom_traits.h"
 #include "third_party/abseil-cpp/absl/types/variant.h"
@@ -121,6 +122,19 @@
 }
 
 // static
+bool StructTraits<autofill::mojom::SectionAutocompleteDataView,
+                  autofill::Section::Autocomplete>::
+    Read(autofill::mojom::SectionAutocompleteDataView data,
+         autofill::Section::Autocomplete* out) {
+  if (!data.ReadSection(&out->section))
+    return false;
+  static_assert(sizeof(data.html_field_mode()) <=
+                sizeof(autofill::HtmlFieldMode));
+  out->mode = static_cast<autofill::HtmlFieldMode>(data.html_field_mode());
+  return true;
+}
+
+// static
 bool StructTraits<autofill::mojom::SectionFieldIdentifierDataView,
                   autofill::Section::FieldIdentifier>::
     Read(autofill::mojom::SectionFieldIdentifierDataView data,
diff --git a/components/autofill/core/common/mojom/autofill_types_mojom_traits.h b/components/autofill/core/common/mojom/autofill_types_mojom_traits.h
index 5c3a752..0710814 100644
--- a/components/autofill/core/common/mojom/autofill_types_mojom_traits.h
+++ b/components/autofill/core/common/mojom/autofill_types_mojom_traits.h
@@ -120,8 +120,22 @@
                    autofill::Section::SectionPrefix* out);
 };
 
-// Converts Autofill::Section::FieldIdentifier into the union
-// mojom::Section::FieldIdentifier.
+template <>
+struct StructTraits<autofill::mojom::SectionAutocompleteDataView,
+                    autofill::Section::Autocomplete> {
+  static const std::string& section(const autofill::Section::Autocomplete& r) {
+    return r.section;
+  }
+
+  static uint8_t html_field_mode(const autofill::Section::Autocomplete& r) {
+    static_assert(sizeof(r.mode) <= sizeof(uint8_t));
+    return r.mode;
+  }
+
+  static bool Read(autofill::mojom::SectionAutocompleteDataView data,
+                   autofill::Section::Autocomplete* out);
+};
+
 template <>
 struct StructTraits<autofill::mojom::SectionFieldIdentifierDataView,
                     autofill::Section::FieldIdentifier> {
diff --git a/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc b/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc
index 7dd828c..d1b2aa77 100644
--- a/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc
+++ b/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc
@@ -276,8 +276,8 @@
 
   // Autocomplete.
   s = Section();
-  s.SetPrefixFromAutocomplete("autocomplete_section",
-                              HtmlFieldMode::HTML_MODE_BILLING);
+  s.SetPrefixFromAutocomplete({.section = "autocomplete_section",
+                               .mode = HtmlFieldMode::HTML_MODE_BILLING});
   s.set_field_type_group(Section::FieldTypeGroupSuffix::kDefault);
   test_cases.push_back(s);
 
@@ -328,8 +328,9 @@
   input.user_input = u"TestTypedValue";
   input.bounds = gfx::RectF(1, 2, 10, 100);
   base::flat_map<LocalFrameToken, size_t> frame_token_ids;
-  input.section.SetPrefixFromAutocomplete("autocomplete_section",
-                                          HtmlFieldMode::HTML_MODE_SHIPPING);
+  input.section.SetPrefixFromAutocomplete(
+      {.section = "autocomplete_section",
+       .mode = HtmlFieldMode::HTML_MODE_SHIPPING});
 
   EXPECT_FALSE(input.host_frame.is_empty());
   base::RunLoop loop;
diff --git a/components/autofill_assistant/browser/actions/action_delegate.h b/components/autofill_assistant/browser/actions/action_delegate.h
index 66fba3c..1f14cbc 100644
--- a/components/autofill_assistant/browser/actions/action_delegate.h
+++ b/components/autofill_assistant/browser/actions/action_delegate.h
@@ -238,11 +238,13 @@
   virtual void GetFullCard(const autofill::CreditCard* credit_card,
                            GetFullCardCallback callback) = 0;
 
-  // Return |FormData| and |FormFieldData| for the element identified with
-  // |selector|. The result is returned asynchronously through |callback|.
+  // Return |FormData| and |FormFieldData| from |RenderFrameHost| for the
+  // element identified with |selector|. The result is returned asynchronously
+  // through |callback|.
   virtual void RetrieveElementFormAndFieldData(
       const Selector& selector,
       base::OnceCallback<void(const ClientStatus&,
+                              content::RenderFrameHost* rfh,
                               const autofill::FormData&,
                               const autofill::FormFieldData&)> callback) = 0;
 
diff --git a/components/autofill_assistant/browser/actions/generate_password_for_form_field_action.cc b/components/autofill_assistant/browser/actions/generate_password_for_form_field_action.cc
index ce9994f..5a0d91d 100644
--- a/components/autofill_assistant/browser/actions/generate_password_for_form_field_action.cc
+++ b/components/autofill_assistant/browser/actions/generate_password_for_form_field_action.cc
@@ -47,6 +47,7 @@
 void GeneratePasswordForFormFieldAction::OnGetFormAndFieldDataForGeneration(
     const std::string& memory_key,
     const ClientStatus& status,
+    content::RenderFrameHost* rfh,
     const autofill::FormData& form_data,
     const autofill::FormFieldData& field_data) {
   if (!status.ok()) {
@@ -57,7 +58,7 @@
   uint64_t max_length = field_data.max_length;
   absl::optional<std::string> password =
       delegate_->GetWebsiteLoginManager()->GeneratePassword(
-          autofill::CalculateFormSignature(form_data),
+          rfh, autofill::CalculateFormSignature(form_data),
           autofill::CalculateFieldSignatureForField(field_data), max_length);
 
   if (!password) {
diff --git a/components/autofill_assistant/browser/actions/generate_password_for_form_field_action.h b/components/autofill_assistant/browser/actions/generate_password_for_form_field_action.h
index 84e8be7..439343c 100644
--- a/components/autofill_assistant/browser/actions/generate_password_for_form_field_action.h
+++ b/components/autofill_assistant/browser/actions/generate_password_for_form_field_action.h
@@ -42,6 +42,7 @@
   void OnGetFormAndFieldDataForGeneration(
       const std::string& memory_key,
       const ClientStatus& status,
+      content::RenderFrameHost* rfh,
       const autofill::FormData& form_data,
       const autofill::FormFieldData& field_data);
 
diff --git a/components/autofill_assistant/browser/actions/generate_password_for_form_field_action_unittest.cc b/components/autofill_assistant/browser/actions/generate_password_for_form_field_action_unittest.cc
index 05b4a0a..0c01069b 100644
--- a/components/autofill_assistant/browser/actions/generate_password_for_form_field_action_unittest.cc
+++ b/components/autofill_assistant/browser/actions/generate_password_for_form_field_action_unittest.cc
@@ -60,7 +60,7 @@
 
 TEST_F(GeneratePasswordForFormFieldActionTest, GeneratedPassword) {
   ON_CALL(mock_action_delegate_, RetrieveElementFormAndFieldData)
-      .WillByDefault(RunOnceCallback<1>(ClientStatus(ACTION_APPLIED),
+      .WillByDefault(RunOnceCallback<1>(ClientStatus(ACTION_APPLIED), nullptr,
                                         autofill::FormData(),
                                         autofill::FormFieldData()));
   GeneratePasswordForFormFieldProto* generate_password_proto =
@@ -84,7 +84,7 @@
 
 TEST_F(GeneratePasswordForFormFieldActionTest, FormDataIsNotRetrieved) {
   ON_CALL(mock_action_delegate_, RetrieveElementFormAndFieldData)
-      .WillByDefault(RunOnceCallback<1>(ClientStatus(INVALID_SELECTOR),
+      .WillByDefault(RunOnceCallback<1>(ClientStatus(INVALID_SELECTOR), nullptr,
                                         autofill::FormData(),
                                         autofill::FormFieldData()));
 
@@ -107,7 +107,7 @@
 
 TEST_F(GeneratePasswordForFormFieldActionTest, GeneratePasswordFails) {
   ON_CALL(mock_action_delegate_, RetrieveElementFormAndFieldData)
-      .WillByDefault(RunOnceCallback<1>(ClientStatus(ACTION_APPLIED),
+      .WillByDefault(RunOnceCallback<1>(ClientStatus(ACTION_APPLIED), nullptr,
                                         autofill::FormData(),
                                         autofill::FormFieldData()));
   GeneratePasswordForFormFieldProto* generate_password_proto =
diff --git a/components/autofill_assistant/browser/actions/mock_action_delegate.h b/components/autofill_assistant/browser/actions/mock_action_delegate.h
index 6322a514..35ee85d 100644
--- a/components/autofill_assistant/browser/actions/mock_action_delegate.h
+++ b/components/autofill_assistant/browser/actions/mock_action_delegate.h
@@ -104,6 +104,7 @@
       RetrieveElementFormAndFieldData,
       void(const Selector& selector,
            base::OnceCallback<void(const ClientStatus&,
+                                   content::RenderFrameHost* rfh,
                                    const autofill::FormData&,
                                    const autofill::FormFieldData&)> callback));
   MOCK_METHOD1(StoreScrolledToElement,
diff --git a/components/autofill_assistant/browser/actions/show_form_action_unittest.cc b/components/autofill_assistant/browser/actions/show_form_action_unittest.cc
index 1d31eeb0..43c47f0 100644
--- a/components/autofill_assistant/browser/actions/show_form_action_unittest.cc
+++ b/components/autofill_assistant/browser/actions/show_form_action_unittest.cc
@@ -153,5 +153,141 @@
   Run();
 }
 
+TEST_F(ShowFormActionTest, SetFormCallFails) {
+  ON_CALL(mock_action_delegate_, SetForm(_, _, _)).WillByDefault(Return(false));
+  EXPECT_CALL(
+      callback_,
+      Run(Pointee(Property(&ProcessedActionProto::status, UNSUPPORTED))));
+
+  proto_.mutable_form();
+  Run();
+}
+
+TEST_F(ShowFormActionTest, FailsWithTooManyBooleanRulesSatisfied) {
+  EXPECT_CALL(
+      mock_action_delegate_,
+      Prompt(Pointee(ElementsAre(Property(&UserAction::enabled, false))), _, _,
+             _, _));
+
+  auto* input = proto_.mutable_form()->add_inputs();
+  auto* counter = input->mutable_counter()->add_counters();
+  counter->set_min_value(0);
+  counter->set_max_value(1);
+  counter->set_label("Counter");
+  auto* rule =
+      input->mutable_counter()->mutable_validation_rule()->mutable_boolean();
+  rule->set_min_satisfied_rules(1);
+  rule->set_max_satisfied_rules(2);
+
+  // All three rules are satisfied.
+  for (int i = 1; i <= 3; ++i) {
+    auto* sub_rule = rule->add_sub_rules()->mutable_counter();
+    sub_rule->set_counter_index(0);
+    sub_rule->set_min_value(i);
+    sub_rule->set_max_value(3);
+  }
+
+  auto* input_result = result_.add_input_results();
+  input_result->mutable_counter()->add_values(3);
+
+  Run();
+}
+
+TEST_F(ShowFormActionTest, FailsWithTooLittleBooleanRulesSatisfied) {
+  EXPECT_CALL(
+      mock_action_delegate_,
+      Prompt(Pointee(ElementsAre(Property(&UserAction::enabled, false))), _, _,
+             _, _));
+
+  auto* input = proto_.mutable_form()->add_inputs();
+  auto* counter = input->mutable_counter()->add_counters();
+  counter->set_min_value(0);
+  counter->set_max_value(1);
+  counter->set_label("Counter");
+  auto* rule =
+      input->mutable_counter()->mutable_validation_rule()->mutable_boolean();
+  rule->set_min_satisfied_rules(1);
+  rule->set_max_satisfied_rules(2);
+
+  // None of the rules are satisfied.
+  for (int i = 1; i <= 3; ++i) {
+    auto* sub_rule = rule->add_sub_rules()->mutable_counter();
+    sub_rule->set_counter_index(0);
+    sub_rule->set_min_value(i);
+    sub_rule->set_max_value(3);
+  }
+
+  auto* input_result = result_.add_input_results();
+  input_result->mutable_counter()->add_values(0);
+
+  Run();
+}
+
+TEST_F(ShowFormActionTest, SucceedsWithEnoughBooleanRulesSatisfied) {
+  EXPECT_CALL(mock_action_delegate_,
+              Prompt(Pointee(ElementsAre(Property(&UserAction::enabled, true))),
+                     _, _, _, _));
+
+  auto* input = proto_.mutable_form()->add_inputs();
+  auto* counter = input->mutable_counter()->add_counters();
+  counter->set_min_value(0);
+  counter->set_max_value(1);
+  counter->set_label("Counter");
+  auto* rule =
+      input->mutable_counter()->mutable_validation_rule()->mutable_boolean();
+  rule->set_min_satisfied_rules(1);
+  rule->set_max_satisfied_rules(2);
+
+  // Only the first rule is satisfied.
+  for (int i = 1; i <= 3; ++i) {
+    auto* sub_rule = rule->add_sub_rules()->mutable_counter();
+    sub_rule->set_counter_index(0);
+    sub_rule->set_min_value(i);
+    sub_rule->set_max_value(3);
+  }
+
+  auto* input_result = result_.add_input_results();
+  input_result->mutable_counter()->add_values(1);
+
+  Run();
+}
+
+TEST_F(ShowFormActionTest, SucceedsInputSelectionValidation) {
+  EXPECT_CALL(mock_action_delegate_,
+              Prompt(Pointee(ElementsAre(Property(&UserAction::enabled, true))),
+                     _, _, _, _));
+
+  auto* input = proto_.mutable_form()->add_inputs();
+  auto* selection = input->mutable_selection();
+  selection->set_min_selected_choices(1);
+  selection->add_choices();
+  selection->add_choices();
+
+  auto* input_result = result_.add_input_results();
+  input_result->mutable_selection()->add_selected(true);
+  input_result->mutable_selection()->add_selected(true);
+
+  Run();
+}
+
+TEST_F(ShowFormActionTest, FailsInputSelectionValidation) {
+  EXPECT_CALL(
+      mock_action_delegate_,
+      Prompt(Pointee(ElementsAre(Property(&UserAction::enabled, false))), _, _,
+             _, _));
+
+  auto* input = proto_.mutable_form()->add_inputs();
+  auto* selection = input->mutable_selection();
+  selection->set_min_selected_choices(2);
+  selection->add_choices();
+  selection->add_choices();
+
+  auto* input_result = result_.add_input_results();
+  input_result->mutable_selection()->add_selected(false);
+  input_result->mutable_selection()->add_selected(true);
+
+  Run();
+}
+
 }  // namespace
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/android/starter_delegate_android.cc b/components/autofill_assistant/browser/android/starter_delegate_android.cc
index a1c01541..2c2dda0 100644
--- a/components/autofill_assistant/browser/android/starter_delegate_android.cc
+++ b/components/autofill_assistant/browser/android/starter_delegate_android.cc
@@ -261,6 +261,11 @@
       GetWebContents().GetBrowserContext());
 }
 
+bool StarterDelegateAndroid::GetIsAllowedForMachineLearning() {
+  return GetCommonDependencies()->IsAllowedForMachineLearning(
+      GetWebContents().GetBrowserContext());
+}
+
 bool StarterDelegateAndroid::GetIsCustomTab() const {
   return dependencies_->GetPlatformDependencies()->IsCustomTab(
       GetWebContents());
diff --git a/components/autofill_assistant/browser/android/starter_delegate_android.h b/components/autofill_assistant/browser/android/starter_delegate_android.h
index 966858b..e41e73a 100644
--- a/components/autofill_assistant/browser/android/starter_delegate_android.h
+++ b/components/autofill_assistant/browser/android/starter_delegate_android.h
@@ -80,6 +80,7 @@
   bool GetMakeSearchesAndBrowsingBetterEnabled() const override;
   bool GetIsLoggedIn() override;
   bool GetIsSupervisedUser() override;
+  bool GetIsAllowedForMachineLearning() override;
   bool GetIsCustomTab() const override;
   bool GetIsWebLayer() const override;
   bool GetIsTabCreatedByGSA() const override;
diff --git a/components/autofill_assistant/browser/common_dependencies.cc b/components/autofill_assistant/browser/common_dependencies.cc
index e1b64870..9959c6c0 100644
--- a/components/autofill_assistant/browser/common_dependencies.cc
+++ b/components/autofill_assistant/browser/common_dependencies.cc
@@ -8,4 +8,9 @@
 
 CommonDependencies::~CommonDependencies() = default;
 
+bool CommonDependencies::IsAllowedForMachineLearning(
+    content::BrowserContext* browser_context) const {
+  return true;
+}
+
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/common_dependencies.h b/components/autofill_assistant/browser/common_dependencies.h
index 518c4db1..90210aa 100644
--- a/components/autofill_assistant/browser/common_dependencies.h
+++ b/components/autofill_assistant/browser/common_dependencies.h
@@ -61,6 +61,9 @@
   virtual bool IsSupervisedUser(
       content::BrowserContext* browser_context) const = 0;
 
+  virtual bool IsAllowedForMachineLearning(
+      content::BrowserContext* browser_context) const;
+
   virtual AnnotateDomModelService* GetOrCreateAnnotateDomModelService(
       content::BrowserContext* browser_context) const = 0;
 
diff --git a/components/autofill_assistant/browser/desktop/starter_delegate_desktop.cc b/components/autofill_assistant/browser/desktop/starter_delegate_desktop.cc
index e560c93a..d2af1db21 100644
--- a/components/autofill_assistant/browser/desktop/starter_delegate_desktop.cc
+++ b/components/autofill_assistant/browser/desktop/starter_delegate_desktop.cc
@@ -108,6 +108,11 @@
       GetWebContents().GetBrowserContext());
 }
 
+bool StarterDelegateDesktop::GetIsAllowedForMachineLearning() {
+  return common_dependencies_->IsAllowedForMachineLearning(
+      GetWebContents().GetBrowserContext());
+}
+
 bool StarterDelegateDesktop::GetIsCustomTab() const {
   return platform_dependencies_->IsCustomTab(GetWebContents());
 }
diff --git a/components/autofill_assistant/browser/desktop/starter_delegate_desktop.h b/components/autofill_assistant/browser/desktop/starter_delegate_desktop.h
index edc069e8..10eb5cf 100644
--- a/components/autofill_assistant/browser/desktop/starter_delegate_desktop.h
+++ b/components/autofill_assistant/browser/desktop/starter_delegate_desktop.h
@@ -63,6 +63,7 @@
   bool GetMakeSearchesAndBrowsingBetterEnabled() const override;
   bool GetIsLoggedIn() override;
   bool GetIsSupervisedUser() override;
+  bool GetIsAllowedForMachineLearning() override;
   bool GetIsCustomTab() const override;
   bool GetIsWebLayer() const override;
   bool GetIsTabCreatedByGSA() const override;
diff --git a/components/autofill_assistant/browser/fake_common_dependencies.cc b/components/autofill_assistant/browser/fake_common_dependencies.cc
index 28cf7fd..3604ffa 100644
--- a/components/autofill_assistant/browser/fake_common_dependencies.cc
+++ b/components/autofill_assistant/browser/fake_common_dependencies.cc
@@ -43,6 +43,11 @@
   return is_supervised_user_;
 }
 
+bool FakeCommonDependencies::IsAllowedForMachineLearning(
+    content::BrowserContext* browser_context) const {
+  return is_allowed_for_machine_learning_;
+}
+
 AnnotateDomModelService*
 FakeCommonDependencies::GetOrCreateAnnotateDomModelService(
     content::BrowserContext* browser_context) const {
diff --git a/components/autofill_assistant/browser/fake_common_dependencies.h b/components/autofill_assistant/browser/fake_common_dependencies.h
index 5723145..5354176f 100644
--- a/components/autofill_assistant/browser/fake_common_dependencies.h
+++ b/components/autofill_assistant/browser/fake_common_dependencies.h
@@ -28,6 +28,8 @@
       content::BrowserContext* browser_context) const override;
   bool IsSupervisedUser(
       content::BrowserContext* browser_context) const override;
+  bool IsAllowedForMachineLearning(
+      content::BrowserContext* browser_context) const override;
   AnnotateDomModelService* GetOrCreateAnnotateDomModelService(
       content::BrowserContext* browser_context) const override;
   bool IsWebLayer() const override;
@@ -40,6 +42,7 @@
   std::string country_code_;
   std::string signed_in_email_;
   bool is_supervised_user_ = false;
+  bool is_allowed_for_machine_learning_ = true;
   bool is_weblayer_ = false;
   version_info::Channel channel_ = version_info::Channel::UNKNOWN;
 };
diff --git a/components/autofill_assistant/browser/fake_starter_platform_delegate.cc b/components/autofill_assistant/browser/fake_starter_platform_delegate.cc
index 4205034..aa3be14 100644
--- a/components/autofill_assistant/browser/fake_starter_platform_delegate.cc
+++ b/components/autofill_assistant/browser/fake_starter_platform_delegate.cc
@@ -111,6 +111,10 @@
   return is_supervised_user_;
 }
 
+bool FakeStarterPlatformDelegate::GetIsAllowedForMachineLearning() {
+  return is_allowed_for_machine_learning_;
+}
+
 bool FakeStarterPlatformDelegate::GetIsCustomTab() const {
   return is_custom_tab_;
 }
diff --git a/components/autofill_assistant/browser/fake_starter_platform_delegate.h b/components/autofill_assistant/browser/fake_starter_platform_delegate.h
index e4fd61f..c05366fb 100644
--- a/components/autofill_assistant/browser/fake_starter_platform_delegate.h
+++ b/components/autofill_assistant/browser/fake_starter_platform_delegate.h
@@ -53,6 +53,7 @@
   bool GetMakeSearchesAndBrowsingBetterEnabled() const override;
   bool GetIsLoggedIn() override;
   bool GetIsSupervisedUser() override;
+  bool GetIsAllowedForMachineLearning() override;
   bool GetIsCustomTab() const override;
   bool GetIsWebLayer() const override;
   bool GetIsTabCreatedByGSA() const override;
@@ -84,6 +85,7 @@
   bool msbb_enabled_ = true;
   bool is_logged_in_ = true;
   bool is_supervised_user_ = false;
+  bool is_allowed_for_machine_learning_ = true;
   bool is_custom_tab_ = true;
   bool is_web_layer_ = true;
   bool is_tab_created_by_gsa_ = true;
diff --git a/components/autofill_assistant/browser/mock_common_dependencies.h b/components/autofill_assistant/browser/mock_common_dependencies.h
index a500b44..a00619f 100644
--- a/components/autofill_assistant/browser/mock_common_dependencies.h
+++ b/components/autofill_assistant/browser/mock_common_dependencies.h
@@ -38,6 +38,10 @@
               IsSupervisedUser,
               (content::BrowserContext*),
               (const override));
+  MOCK_METHOD(bool,
+              IsAllowedForMachineLearning,
+              (content::BrowserContext*),
+              (const override));
   MOCK_METHOD(AnnotateDomModelService*,
               GetOrCreateAnnotateDomModelService,
               (content::BrowserContext*),
diff --git a/components/autofill_assistant/browser/public/password_change/empty_website_login_manager_impl.cc b/components/autofill_assistant/browser/public/password_change/empty_website_login_manager_impl.cc
index 5046f5c5..4280b6a 100644
--- a/components/autofill_assistant/browser/public/password_change/empty_website_login_manager_impl.cc
+++ b/components/autofill_assistant/browser/public/password_change/empty_website_login_manager_impl.cc
@@ -49,6 +49,7 @@
 }
 
 absl::optional<std::string> EmptyWebsiteLoginManagerImpl::GeneratePassword(
+    content::RenderFrameHost* rfh,
     autofill::FormSignature form_signature,
     autofill::FieldSignature field_signature,
     uint64_t max_length) {
diff --git a/components/autofill_assistant/browser/public/password_change/empty_website_login_manager_impl.h b/components/autofill_assistant/browser/public/password_change/empty_website_login_manager_impl.h
index d615906..4cf70ff0 100644
--- a/components/autofill_assistant/browser/public/password_change/empty_website_login_manager_impl.h
+++ b/components/autofill_assistant/browser/public/password_change/empty_website_login_manager_impl.h
@@ -40,6 +40,7 @@
                             const std::string& new_password,
                             base::OnceCallback<void(bool)> callback) override;
   absl::optional<std::string> GeneratePassword(
+      content::RenderFrameHost* rfh,
       autofill::FormSignature form_signature,
       autofill::FieldSignature field_signature,
       uint64_t max_length) override;
diff --git a/components/autofill_assistant/browser/public/password_change/mock_website_login_manager.h b/components/autofill_assistant/browser/public/password_change/mock_website_login_manager.h
index fed3e62..0b6afe5 100644
--- a/components/autofill_assistant/browser/public/password_change/mock_website_login_manager.h
+++ b/components/autofill_assistant/browser/public/password_change/mock_website_login_manager.h
@@ -47,7 +47,8 @@
 
   MOCK_METHOD(absl::optional<std::string>,
               GeneratePassword,
-              (autofill::FormSignature form_signature,
+              (content::RenderFrameHost * rfh,
+               autofill::FormSignature form_signature,
                autofill::FieldSignature field_signature,
                uint64_t max_length),
               (override));
diff --git a/components/autofill_assistant/browser/public/password_change/website_login_manager.h b/components/autofill_assistant/browser/public/password_change/website_login_manager.h
index c4ecaed45..6bd984b 100644
--- a/components/autofill_assistant/browser/public/password_change/website_login_manager.h
+++ b/components/autofill_assistant/browser/public/password_change/website_login_manager.h
@@ -17,6 +17,10 @@
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 
+namespace content {
+class RenderFrameHost;
+}
+
 namespace autofill_assistant {
 
 // Common interface for implementations that fetch login details for websites.
@@ -69,13 +73,13 @@
       const Login& login,
       base::OnceCallback<void(absl::optional<base::Time>)> callback) = 0;
 
-  // Generates new strong password. |form/field_signature| are used to fetch
-  // password requirements. |max_length| is the "max_length" attribute of input
-  // field that limits the length of value.
-  // Stores the generated password in `generated_password` and
-  // returns |absl::nullopt| if the password cannot be generated for some
-  // reason.
+  // Generates new strong password. |rfh| and |form/field_signature| are used to
+  // fetch password requirements. |max_length| is the "max_length" attribute of
+  // input field that limits the length of value. Stores the generated password
+  // in `generated_password` and returns |absl::nullopt| if the password cannot
+  // be generated for some reason.
   virtual absl::optional<std::string> GeneratePassword(
+      content::RenderFrameHost* rfh,
       autofill::FormSignature form_signature,
       autofill::FieldSignature field_signature,
       uint64_t max_length) = 0;
diff --git a/components/autofill_assistant/browser/public/password_change/website_login_manager_impl.cc b/components/autofill_assistant/browser/public/password_change/website_login_manager_impl.cc
index bff0228..3868d3c 100644
--- a/components/autofill_assistant/browser/public/password_change/website_login_manager_impl.cc
+++ b/components/autofill_assistant/browser/public/password_change/website_login_manager_impl.cc
@@ -455,22 +455,21 @@
                      weak_ptr_factory_.GetWeakPtr())));
   pending_requests_.back()->Start();
 }
+
 absl::optional<std::string> WebsiteLoginManagerImpl::GeneratePassword(
+    content::RenderFrameHost* rfh,
     autofill::FormSignature form_signature,
     autofill::FieldSignature field_signature,
     uint64_t max_length) {
+  if (!rfh)
+    return absl::nullopt;
   auto* factory =
       password_manager::ContentPasswordManagerDriverFactory::FromWebContents(
           web_contents_);
   DCHECK(factory);
-  // TODO(crbug.com/1043132): Add support for non-main frames. If another
-  // frame has a different origin than the main frame, passwords-related
-  // features may not work.
-  auto* driver =
-      factory->GetDriverForFrame(web_contents_->GetPrimaryMainFrame());
-  if (!driver) {
+  auto* driver = factory->GetDriverForFrame(rfh);
+  if (!driver)
     return absl::nullopt;
-  }
   generated_password_ =
       base::UTF16ToUTF8(driver->GetPasswordGenerationHelper()->GeneratePassword(
           driver->GetLastCommittedURL(), form_signature, field_signature,
diff --git a/components/autofill_assistant/browser/public/password_change/website_login_manager_impl.h b/components/autofill_assistant/browser/public/password_change/website_login_manager_impl.h
index 62007e7..d1c6553 100644
--- a/components/autofill_assistant/browser/public/password_change/website_login_manager_impl.h
+++ b/components/autofill_assistant/browser/public/password_change/website_login_manager_impl.h
@@ -47,6 +47,7 @@
                             const std::string& new_password,
                             base::OnceCallback<void(bool)> callback) override;
   absl::optional<std::string> GeneratePassword(
+      content::RenderFrameHost* rfh,
       autofill::FormSignature form_signature,
       autofill::FieldSignature field_signature,
       uint64_t max_length) override;
diff --git a/components/autofill_assistant/browser/public/password_change/website_login_manager_impl_unittest.cc b/components/autofill_assistant/browser/public/password_change/website_login_manager_impl_unittest.cc
index 40f4e61d..0bd6d5b2 100644
--- a/components/autofill_assistant/browser/public/password_change/website_login_manager_impl_unittest.cc
+++ b/components/autofill_assistant/browser/public/password_change/website_login_manager_impl_unittest.cc
@@ -429,4 +429,12 @@
   EXPECT_FALSE(manager_->SaveSubmittedPassword());
 }
 
+TEST_F(WebsiteLoginManagerImplTest, GeneratePasswordForNullRenderFrameHost) {
+  EXPECT_EQ(
+      absl::nullopt,
+      // The arguments other than the `render_frame_host` are arbitrary.
+      manager_->GeneratePassword(/*rfh=*/nullptr, autofill::FormSignature(123),
+                                 autofill::FieldSignature(456), 10));
+}
+
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/script_executor.cc b/components/autofill_assistant/browser/script_executor.cc
index fa49e26..f0deb85 100644
--- a/components/autofill_assistant/browser/script_executor.cc
+++ b/components/autofill_assistant/browser/script_executor.cc
@@ -480,6 +480,7 @@
 void ScriptExecutor::RetrieveElementFormAndFieldData(
     const Selector& selector,
     base::OnceCallback<void(const ClientStatus&,
+                            content::RenderFrameHost* rfh,
                             const autofill::FormData&,
                             const autofill::FormFieldData&)> callback) {
   delegate_->GetWebController()->RetrieveElementFormAndFieldData(
diff --git a/components/autofill_assistant/browser/script_executor.h b/components/autofill_assistant/browser/script_executor.h
index b8879ba2..623307b 100644
--- a/components/autofill_assistant/browser/script_executor.h
+++ b/components/autofill_assistant/browser/script_executor.h
@@ -180,6 +180,7 @@
   void RetrieveElementFormAndFieldData(
       const Selector& selector,
       base::OnceCallback<void(const ClientStatus&,
+                              content::RenderFrameHost* rfh,
                               const autofill::FormData& form_data,
                               const autofill::FormFieldData& field_data)>
           callback) override;
diff --git a/components/autofill_assistant/browser/starter.cc b/components/autofill_assistant/browser/starter.cc
index 2c7de97b..48c24a5c 100644
--- a/components/autofill_assistant/browser/starter.cc
+++ b/components/autofill_assistant/browser/starter.cc
@@ -474,7 +474,8 @@
     return;
   }
 
-  if (platform_delegate_->GetIsSupervisedUser()) {
+  if (platform_delegate_->GetIsSupervisedUser() ||
+      !platform_delegate_->GetIsAllowedForMachineLearning()) {
     OnStartDone(/* start_script= */ false);
     return;
   }
diff --git a/components/autofill_assistant/browser/starter_heuristic_configs/finch_starter_heuristic_config.cc b/components/autofill_assistant/browser/starter_heuristic_configs/finch_starter_heuristic_config.cc
index a922c9b..c4a4136 100644
--- a/components/autofill_assistant/browser/starter_heuristic_configs/finch_starter_heuristic_config.cc
+++ b/components/autofill_assistant/browser/starter_heuristic_configs/finch_starter_heuristic_config.cc
@@ -24,7 +24,8 @@
     StarterPlatformDelegate* platform_delegate) const {
   static const base::NoDestructor<base::Value> empty_list(
       base::Value::Type::LIST);
-  if (platform_delegate->GetIsSupervisedUser()) {
+  if (platform_delegate->GetIsSupervisedUser() ||
+      !platform_delegate->GetIsAllowedForMachineLearning()) {
     return empty_list->GetList();
   }
 
diff --git a/components/autofill_assistant/browser/starter_heuristic_configs/finch_starter_heuristic_config_unittest.cc b/components/autofill_assistant/browser/starter_heuristic_configs/finch_starter_heuristic_config_unittest.cc
index 57eb20a5..26e3ad7 100644
--- a/components/autofill_assistant/browser/starter_heuristic_configs/finch_starter_heuristic_config_unittest.cc
+++ b/components/autofill_assistant/browser/starter_heuristic_configs/finch_starter_heuristic_config_unittest.cc
@@ -107,6 +107,21 @@
               SizeIs(1));
 }
 
+TEST_F(FinchStarterHeuristicConfigTest,
+       DisabledForNotAllowedForMachineLearningUsers) {
+  InitDefaultHeuristic(features::kAutofillAssistantUrlHeuristic1, "some_key");
+  FinchStarterHeuristicConfig config(base::FeatureParam<std::string>{
+      &features::kAutofillAssistantUrlHeuristic1, "some_key", ""});
+
+  fake_platform_delegate_.is_allowed_for_machine_learning_ = false;
+  EXPECT_THAT(config.GetConditionSetsForClientState(&fake_platform_delegate_),
+              IsEmpty());
+
+  fake_platform_delegate_.is_allowed_for_machine_learning_ = true;
+  EXPECT_THAT(config.GetConditionSetsForClientState(&fake_platform_delegate_),
+              SizeIs(1));
+}
+
 TEST_F(FinchStarterHeuristicConfigTest, DisabledIfProactiveHelpSettingOff) {
   InitDefaultHeuristic(features::kAutofillAssistantUrlHeuristic1, "some_key");
   FinchStarterHeuristicConfig config(base::FeatureParam<std::string>{
diff --git a/components/autofill_assistant/browser/starter_heuristic_configs/legacy_starter_heuristic_config.cc b/components/autofill_assistant/browser/starter_heuristic_configs/legacy_starter_heuristic_config.cc
index a406d0e..fb063f78 100644
--- a/components/autofill_assistant/browser/starter_heuristic_configs/legacy_starter_heuristic_config.cc
+++ b/components/autofill_assistant/browser/starter_heuristic_configs/legacy_starter_heuristic_config.cc
@@ -30,7 +30,8 @@
     StarterPlatformDelegate* platform_delegate) const {
   static const base::NoDestructor<base::Value> empty_list(
       base::Value::Type::LIST);
-  if (platform_delegate->GetIsSupervisedUser()) {
+  if (platform_delegate->GetIsSupervisedUser() ||
+      !platform_delegate->GetIsAllowedForMachineLearning()) {
     return empty_list->GetList();
   }
 
diff --git a/components/autofill_assistant/browser/starter_heuristic_configs/legacy_starter_heuristic_config_unittest.cc b/components/autofill_assistant/browser/starter_heuristic_configs/legacy_starter_heuristic_config_unittest.cc
index 2518fdf..419201c 100644
--- a/components/autofill_assistant/browser/starter_heuristic_configs/legacy_starter_heuristic_config_unittest.cc
+++ b/components/autofill_assistant/browser/starter_heuristic_configs/legacy_starter_heuristic_config_unittest.cc
@@ -358,6 +358,25 @@
               SizeIs(1));
 }
 
+TEST_F(LegacyStarterHeuristicConfigTest,
+       DisabledForNotAllowedForMachineLearningUsers) {
+  InitDefaultHeuristic();
+  auto scoped_feature_list = std::make_unique<base::test::ScopedFeatureList>();
+  scoped_feature_list->InitWithFeatures(
+      /* enabled_features = */ {features::kAutofillAssistantInTabTriggering,
+                                features::kAutofillAssistantInCCTTriggering},
+      /* disabled_features = */ {});
+  LegacyStarterHeuristicConfig config;
+
+  fake_platform_delegate_.is_allowed_for_machine_learning_ = false;
+  EXPECT_THAT(config.GetConditionSetsForClientState(&fake_platform_delegate_),
+              IsEmpty());
+
+  fake_platform_delegate_.is_allowed_for_machine_learning_ = true;
+  EXPECT_THAT(config.GetConditionSetsForClientState(&fake_platform_delegate_),
+              SizeIs(1));
+}
+
 TEST_F(LegacyStarterHeuristicConfigTest, DisabledIfProactiveHelpSettingOff) {
   InitDefaultHeuristic();
   auto scoped_feature_list = std::make_unique<base::test::ScopedFeatureList>();
diff --git a/components/autofill_assistant/browser/starter_platform_delegate.h b/components/autofill_assistant/browser/starter_platform_delegate.h
index 86bc519..b670b95 100644
--- a/components/autofill_assistant/browser/starter_platform_delegate.h
+++ b/components/autofill_assistant/browser/starter_platform_delegate.h
@@ -91,6 +91,8 @@
   virtual bool GetIsLoggedIn() = 0;
   // Returns whether the user is restricted to any supervision.
   virtual bool GetIsSupervisedUser() = 0;
+  // Returns whether the user is allowed for machine learning.
+  virtual bool GetIsAllowedForMachineLearning() = 0;
   // Returns whether this is a custom tab or not.
   virtual bool GetIsCustomTab() const = 0;
   // Returns whether this is running in WebLayer or not.
diff --git a/components/autofill_assistant/browser/starter_unittest.cc b/components/autofill_assistant/browser/starter_unittest.cc
index ea5bf49..7150feb 100644
--- a/components/autofill_assistant/browser/starter_unittest.cc
+++ b/components/autofill_assistant/browser/starter_unittest.cc
@@ -2389,4 +2389,40 @@
       TriggerContext::Options()));
 }
 
+TEST_F(StarterTest, RegularStartupFailsForNotAllowedForMachineLearningUsers) {
+  SetupPlatformDelegateForReturningUser();
+  fake_platform_delegate_.is_allowed_for_machine_learning_ = false;
+
+  base::flat_map<std::string, std::string> script_parameters = {
+      {"ENABLED", "true"},
+      {"START_IMMEDIATELY", "true"},
+      {"ORIGINAL_DEEPLINK", kExampleDeeplink}};
+  TriggerContext::Options options;
+  options.initial_url = "https://redirect.com/to/www/example/com";
+  EXPECT_CALL(mock_start_regular_script_callback_, Run).Times(0);
+
+  starter_->Start(std::make_unique<TriggerContext>(
+      std::make_unique<ScriptParameters>(script_parameters), options));
+}
+
+TEST_F(StarterTest,
+       RpcTriggerScriptStartupFailsForAllowedForMachineLearningUsers) {
+  SetupPlatformDelegateForReturningUser();
+  fake_platform_delegate_.is_allowed_for_machine_learning_ = false;
+
+  base::flat_map<std::string, std::string> script_parameters = {
+      {"ENABLED", "true"},
+      {"START_IMMEDIATELY", "false"},
+      {"REQUEST_TRIGGER_SCRIPT", "true"},
+      {"ORIGINAL_DEEPLINK", kExampleDeeplink}};
+  EXPECT_CALL(*mock_trigger_script_ui_delegate_, Attach).Times(0);
+  EXPECT_CALL(*mock_trigger_script_service_request_sender_, OnSendRequest)
+      .Times(0);
+  EXPECT_CALL(mock_start_regular_script_callback_, Run).Times(0);
+
+  starter_->Start(std::make_unique<TriggerContext>(
+      std::make_unique<ScriptParameters>(script_parameters),
+      TriggerContext::Options()));
+}
+
 }  // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/web/web_controller.cc b/components/autofill_assistant/browser/web/web_controller.cc
index 4afa69e..f16c0af 100644
--- a/components/autofill_assistant/browser/web/web_controller.cc
+++ b/components/autofill_assistant/browser/web/web_controller.cc
@@ -964,6 +964,7 @@
 void WebController::RetrieveElementFormAndFieldData(
     const Selector& selector,
     base::OnceCallback<void(const ClientStatus&,
+                            content::RenderFrameHost* rfh,
                             const autofill::FormData& form_data,
                             const autofill::FormFieldData& field_data)>
         callback) {
@@ -977,6 +978,7 @@
 
 void WebController::OnFindElementForRetrieveElementFormAndFieldData(
     base::OnceCallback<void(const ClientStatus&,
+                            content::RenderFrameHost* rfh,
                             const autofill::FormData& form_data,
                             const autofill::FormFieldData& field_data)>
         callback,
@@ -985,8 +987,8 @@
   if (!element_status.ok()) {
     DVLOG(1) << __func__
              << " Failed to find the element for getting Autofill data.";
-    std::move(callback).Run(element_status, autofill::FormData(),
-                            autofill::FormFieldData());
+    std::move(callback).Run(element_status, element_result->render_frame_host(),
+                            autofill::FormData(), autofill::FormFieldData());
     return;
   }
 
@@ -1092,6 +1094,7 @@
 void WebController::OnGetFormAndFieldDataForRetrieving(
     std::unique_ptr<ElementFinderResult> element,
     base::OnceCallback<void(const ClientStatus&,
+                            content::RenderFrameHost* rfh,
                             const autofill::FormData& form_data,
                             const autofill::FormFieldData& field_data)>
         callback,
@@ -1099,7 +1102,8 @@
     ContentAutofillDriver* driver,
     const autofill::FormData& form_data,
     const autofill::FormFieldData& form_field) {
-  std::move(callback).Run(form_status, form_data, form_field);
+  std::move(callback).Run(form_status, element->render_frame_host(), form_data,
+                          form_field);
 }
 
 void WebController::SelectOption(
diff --git a/components/autofill_assistant/browser/web/web_controller.h b/components/autofill_assistant/browser/web/web_controller.h
index f8f0f1e..2d2be4fd8 100644
--- a/components/autofill_assistant/browser/web/web_controller.h
+++ b/components/autofill_assistant/browser/web/web_controller.h
@@ -201,11 +201,13 @@
       const ElementFinderResult& element,
       base::OnceCallback<void(const ClientStatus&)> callback);
 
-  // Return |FormData| and |FormFieldData| for the element identified with
-  // |selector|. The result is returned asynchronously through |callback|.
+  // Return |FormData| and |FormFieldData| from |RenderFrameHost| for the
+  // element identified with |selector|. The result is returned asynchronously
+  // through |callback|.
   virtual void RetrieveElementFormAndFieldData(
       const Selector& selector,
       base::OnceCallback<void(const ClientStatus&,
+                              content::RenderFrameHost* rfh,
                               const autofill::FormData& form_data,
                               const autofill::FormFieldData& field_data)>
           callback);
@@ -460,6 +462,7 @@
   void OnSelectorObserverFinished(SelectorObserver* observer);
   void OnFindElementForRetrieveElementFormAndFieldData(
       base::OnceCallback<void(const ClientStatus&,
+                              content::RenderFrameHost* rfh,
                               const autofill::FormData& form_data,
                               const autofill::FormFieldData& field_data)>
           callback,
@@ -500,6 +503,7 @@
   void OnGetFormAndFieldDataForRetrieving(
       std::unique_ptr<ElementFinderResult> element,
       base::OnceCallback<void(const ClientStatus&,
+                              content::RenderFrameHost* rfh,
                               const autofill::FormData& form_data,
                               const autofill::FormFieldData& field_data)>
           callback,
diff --git a/components/browser_ui/strings/android/browser_ui_strings.grd b/components/browser_ui/strings/android/browser_ui_strings.grd
index 69eacf0..b43bbee3 100644
--- a/components/browser_ui/strings/android/browser_ui_strings.grd
+++ b/components/browser_ui/strings/android/browser_ui_strings.grd
@@ -464,6 +464,9 @@
       <message name="IDS_PAGE_INFO_ABOUT_THIS_PAGE_TITLE" desc="The title of the 'About this page' row in the Page Info bubble.">
         About this page
       </message>
+      <message name="IDS_PAGE_INFO_ABOUT_THIS_PAGE_DESCRIPTION_PLACEHOLDER" desc="The description of the 'About this page' row in the Page Info bubble if no more detailed description is available. 'It' refers to the page the user is currently visiting.">
+        Learn about its source and topic
+      </message>
       <message name="IDS_PAGE_INFO_ABOUT_THIS_SITE_SUBPAGE_FROM_LABEL" desc="The label containing the source of the description in the 'About this site' subpage in Page Info bubble.">
         From <ph name="SOURCE_NAME">%1$s<ex>Wikipedia</ex></ph>
       </message>
diff --git a/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_ABOUT_THIS_PAGE_DESCRIPTION_PLACEHOLDER.png.sha1 b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_ABOUT_THIS_PAGE_DESCRIPTION_PLACEHOLDER.png.sha1
new file mode 100644
index 0000000..6d46332
--- /dev/null
+++ b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_ABOUT_THIS_PAGE_DESCRIPTION_PLACEHOLDER.png.sha1
@@ -0,0 +1 @@
+d1e31caf939d4a8f5520701437e436e2c50925ec
\ No newline at end of file
diff --git a/components/device_reauth/biometric_authenticator.h b/components/device_reauth/biometric_authenticator.h
index fdf2baaa..e13030b 100644
--- a/components/device_reauth/biometric_authenticator.h
+++ b/components/device_reauth/biometric_authenticator.h
@@ -42,7 +42,11 @@
   // lock setting in on and Chrome came to foreground.
   kIncognitoReauthPage = 6,
 
-  kMaxValue = kIncognitoReauthPage,
+  // The prompt displayed when user is trying to copy/edit/view/export their
+  // passwords from settings page on Windows and Mac.
+  kPasswordsInSettings = 7,
+
+  kMaxValue = kPasswordsInSettings,
 };
 
 // This interface encapsulates operations related to biometric authentication.
diff --git a/components/exo/data_offer.cc b/components/exo/data_offer.cc
index 5c7b874..6a89a33 100644
--- a/components/exo/data_offer.cc
+++ b/components/exo/data_offer.cc
@@ -25,9 +25,6 @@
 #include "components/exo/data_offer_delegate.h"
 #include "components/exo/data_offer_observer.h"
 #include "net/base/filename_util.h"
-#include "third_party/skia/include/core/SkEncodedImageFormat.h"
-#include "third_party/skia/include/core/SkImageEncoder.h"
-#include "third_party/skia/include/core/SkStream.h"
 #include "ui/base/clipboard/clipboard.h"
 #include "ui/base/clipboard/clipboard_buffer.h"
 #include "ui/base/clipboard/clipboard_constants.h"
diff --git a/components/history/core/browser/keyword_search_term_util.cc b/components/history/core/browser/keyword_search_term_util.cc
index b06155ec..55da0d3b 100644
--- a/components/history/core/browser/keyword_search_term_util.cc
+++ b/components/history/core/browser/keyword_search_term_util.cc
@@ -12,11 +12,10 @@
 namespace {
 
 // Calculates the score for the given number of visits in a given day.
-// Recent visits count more than historical ones, so we multiply in a boost
+// Recent visits count more than historical ones, so multiply in a boost
 // depending on how long ago this day was. This boost is a curve that
 // smoothly goes through these values: Today gets 3x, a week ago 2x, three
-// weeks ago 1.5x, falling off to 1x at the limit of how far we reach into
-// the past.
+// weeks ago 1.5x, gradually falling off to 1x at the very end.
 double GetMostVisitedFrecencyScore(int visit_count,
                                    base::Time day,
                                    base::Time now) {
@@ -28,19 +27,21 @@
 
 // Returns whether two search terms are identical, i.e., have the same
 // normalized search terms.
-bool IsSameSearchTerm(const KeywordSearchTermVisit& search_term,
-                      const KeywordSearchTermVisit& other_search_term) {
-  return search_term.normalized_term == other_search_term.normalized_term;
+bool IsSameSearchTerm(const KeywordSearchTermVisit& search_term_visit,
+                      const KeywordSearchTermVisit& other_search_term_visit) {
+  return search_term_visit.normalized_term ==
+         other_search_term_visit.normalized_term;
 }
 
-// Return whether a visit to a search term is a duplicative visit, i.e., a visit
-// to the same search term in an interval smaller than
+// Return whether a visit to a search term constitutes a duplicate visit, i.e.,
+// a visit to the same search term in an interval smaller than
 // kAutocompleteDuplicateVisitIntervalThreshold.
-bool IsDuplicateVisit(const KeywordSearchTermVisit& search_term,
-                      const KeywordSearchTermVisit& other_search_term) {
-  return IsSameSearchTerm(search_term, other_search_term) &&
-         (search_term.last_visit_time - other_search_term.last_visit_time <=
-          kAutocompleteDuplicateVisitIntervalThreshold);
+// Called with identical search terms only. i.e., IsSameSearchTerm() is true.
+bool IsDuplicateVisit(const KeywordSearchTermVisit& search_term_visit,
+                      const KeywordSearchTermVisit& other_search_term_visit) {
+  return search_term_visit.last_visit_time -
+             other_search_term_visit.last_visit_time <=
+         kAutocompleteDuplicateVisitIntervalThreshold;
 }
 
 // Transforms a visit time to its timeslot, i.e., day of the viist.
@@ -49,10 +50,11 @@
 }
 
 // Returns whether two search term visits are in the same timeslot.
-bool IsSameTimeslot(const KeywordSearchTermVisit& search_term,
-                    const KeywordSearchTermVisit& other_search_term) {
-  return VisitTimeToTimeslot(search_term.last_visit_time) ==
-         VisitTimeToTimeslot(other_search_term.last_visit_time);
+// Called with identical search terms only. i.e., IsSameSearchTerm() is true.
+bool IsSameTimeslot(const KeywordSearchTermVisit& search_term_visit,
+                    const KeywordSearchTermVisit& other_search_term_visit) {
+  return VisitTimeToTimeslot(search_term_visit.last_visit_time) ==
+         VisitTimeToTimeslot(other_search_term_visit.last_visit_time);
 }
 
 }  // namespace
@@ -98,35 +100,32 @@
   std::unique_ptr<KeywordSearchTermVisit> GetNextSearchTermFromEnumerator(
       KeywordSearchTermVisitEnumerator& enumerator,
       bool ignore_duplicate_visits) {
-    // |next_search_term| acts as the fast pointer and |last_search_term_| acts
-    // as the slow pointer accumulating the search term visit count across
-    // visits.
-    while (auto next_search_term = enumerator.GetNextVisit()) {
-      if (ignore_duplicate_visits && last_search_term_ &&
-          IsDuplicateVisit(*next_search_term, *last_search_term_)) {
-        continue;
-      }
-
+    // |next_visit| acts as the fast pointer and |last_search_term_| acts as the
+    // slow pointer accumulating the search term visit counts across visits.
+    while (auto next_visit = enumerator.GetNextVisit()) {
       if (last_search_term_ &&
-          IsSameSearchTerm(*next_search_term, *last_search_term_)) {
-        // We encountered the same search term:
+          IsSameSearchTerm(*next_visit, *last_search_term_)) {
+        if (ignore_duplicate_visits &&
+            IsDuplicateVisit(*next_visit, *last_search_term_)) {
+          continue;
+        }
+        // Encountered the same search term:
         // 1. Move |last_search_term_| forward.
         // 2. Add up the search term visit count.
         int visit_count = last_search_term_->visit_count;
-        last_search_term_ = std::move(next_search_term);
+        last_search_term_ = std::move(next_visit);
         last_search_term_->visit_count += visit_count;
       } else if (last_search_term_) {
-        // We encountered a new search term and |last_search_term_| has a value:
+        // Encountered a new search term and |last_search_term_| has a value:
         // 1. Move |last_search_term_| forward.
         // 2. Return the old |last_search_term_|.
         auto search_term_to_return = std::move(last_search_term_);
-        last_search_term_ = std::move(next_search_term);
+        last_search_term_ = std::move(next_visit);
         return search_term_to_return;
       } else {
-        // We encountered a new search term and |last_search_term_| has no
-        // value:
+        // Encountered a new search term and |last_search_term_| has no value:
         // 1. Move |last_search_term_| forward.
-        last_search_term_ = std::move(next_search_term);
+        last_search_term_ = std::move(next_visit);
       }
     }
 
@@ -181,27 +180,27 @@
   std::unique_ptr<KeywordSearchTermVisit> GetNextSearchTermFromEnumerator(
       KeywordSearchTermVisitEnumerator& enumerator,
       base::Time now) {
-    // |next_search_term| acts as the fast pointer and |last_search_term_| acts
-    // as the slow pointer accumulating the search term score across visits.
-    while (auto next_search_term = enumerator.GetNextVisit()) {
+    // |next_visit| acts as the fast pointer and |last_search_term_| acts as the
+    // slow pointer accumulating the search term score across visits.
+    while (auto next_visit = enumerator.GetNextVisit()) {
       bool is_same_search_term =
           last_search_term_ &&
-          IsSameSearchTerm(*next_search_term, *last_search_term_);
+          IsSameSearchTerm(*next_visit, *last_search_term_);
       if (is_same_search_term &&
-          IsSameTimeslot(*next_search_term, *last_search_term_)) {
-        // We are in the same timeslot for the same search term:
+          IsSameTimeslot(*next_visit, *last_search_term_)) {
+        // The same timeslot for the same search term:
         // 1. Move |last_search_term_| forward.
         // 2. Add up the search term visit count in the timeslot.
         // 3. Carry over the search term score.
         int visit_count = last_search_term_->visit_count;
         double score = last_search_term_->score.value_or(0.0);
-        last_search_term_ = std::move(next_search_term);
+        last_search_term_ = std::move(next_visit);
         last_search_term_->visit_count += visit_count;
         last_search_term_->score =
             last_search_term_->score.value_or(0.0) + score;
 
       } else if (is_same_search_term) {
-        // We are in a new timeslot for the same search term:
+        // A new timeslot for the same search term:
         // 1. Update the search term score by adding the last timeslot's score.
         // 2. Move |last_search_term_| forward.
         // 3. Carry over the search term score.
@@ -210,11 +209,11 @@
             GetMostVisitedFrecencyScore(
                 last_search_term_->visit_count,
                 VisitTimeToTimeslot(last_search_term_->last_visit_time), now);
-        last_search_term_ = std::move(next_search_term);
+        last_search_term_ = std::move(next_visit);
         last_search_term_->score = score;
 
       } else if (last_search_term_) {
-        // We encountered a new search term and |last_search_term_| has a value:
+        // Encountered a new search term and |last_search_term_| has a value:
         // 1. Update the search term score by adding the last timeslot's score.
         // 2. Move |last_search_term_| forward.
         // 3. Return the old |last_search_term_|.
@@ -225,13 +224,12 @@
                 VisitTimeToTimeslot(last_search_term_->last_visit_time), now);
         last_search_term_->score = score;
         auto search_term_to_return = std::move(last_search_term_);
-        last_search_term_ = std::move(next_search_term);
+        last_search_term_ = std::move(next_visit);
         return search_term_to_return;
       } else {
-        // We encountered a new search term and |last_search_term_| has no
-        // value:
+        // Encountered a new search term and |last_search_term_| has no value:
         // 1. Move |last_search_term_| forward.
-        last_search_term_ = std::move(next_search_term);
+        last_search_term_ = std::move(next_visit);
       }
     }
 
diff --git a/components/network_time/network_time_tracker_unittest.cc b/components/network_time/network_time_tracker_unittest.cc
index 841be6e2..37b08d75d 100644
--- a/components/network_time/network_time_tracker_unittest.cc
+++ b/components/network_time/network_time_tracker_unittest.cc
@@ -441,10 +441,10 @@
   EXPECT_EQ(NetworkTimeTracker::NETWORK_TIME_AVAILABLE,
             tracker_->GetNetworkTime(&out_network_time, nullptr));
   absl::optional<double> local, network;
-  const base::Value* saved_prefs =
-      pref_service_.GetDictionary(prefs::kNetworkTimeMapping);
-  local = saved_prefs->FindDoubleKey("local");
-  network = saved_prefs->FindDoubleKey("network");
+  const base::Value::Dict& saved_prefs =
+      pref_service_.GetValueDict(prefs::kNetworkTimeMapping);
+  local = saved_prefs.FindDouble("local");
+  network = saved_prefs.FindDouble("network");
   ASSERT_TRUE(local);
   ASSERT_TRUE(network);
   base::Value::Dict prefs;
diff --git a/components/page_info/core/about_this_site_service.cc b/components/page_info/core/about_this_site_service.cc
index 9c2accd..1256af2e 100644
--- a/components/page_info/core/about_this_site_service.cc
+++ b/components/page_info/core/about_this_site_service.cc
@@ -4,6 +4,7 @@
 
 #include "components/page_info/core/about_this_site_service.h"
 
+#include "base/feature_list.h"
 #include "base/metrics/histogram_functions.h"
 #include "components/optimization_guide/core/optimization_guide_decision.h"
 #include "components/optimization_guide/core/optimization_metadata.h"
@@ -16,9 +17,18 @@
 #include "url/gurl.h"
 
 namespace page_info {
+namespace {
 using AboutThisSiteStatus = about_this_site_validation::AboutThisSiteStatus;
+using AboutThisSiteInteraction = AboutThisSiteService::AboutThisSiteInteraction;
 using OptimizationGuideDecision = optimization_guide::OptimizationGuideDecision;
 
+void RecordAboutThisSiteInteraction(AboutThisSiteInteraction interaction) {
+  base::UmaHistogramEnumeration("Security.PageInfo.AboutThisSiteInteraction",
+                                interaction);
+}
+
+}  // namespace
+
 const char kBannerInteractionHistogram[] =
     "Privacy.AboutThisSite.BannerInteraction";
 
@@ -50,6 +60,13 @@
                 about_this_site_metadata);
   base::UmaHistogramEnumeration("Security.PageInfo.AboutThisSiteStatus",
                                 status);
+  RecordAboutThisSiteInteraction(
+      status == AboutThisSiteStatus::kValid
+          ? (about_this_site_metadata->site_info().has_description()
+                 ? AboutThisSiteInteraction::kShownWithDescription
+                 : AboutThisSiteInteraction::kShownWithoutDescription)
+          : AboutThisSiteInteraction::kNotShown);
+
   ukm::builders::AboutThisSiteStatus(source_id)
       .SetStatus(static_cast<int>(status))
       .Record(ukm::UkmRecorder::Get());
@@ -70,13 +87,16 @@
   if (kShowSampleContent.Get()) {
     page_info::proto::SiteInfo site_info;
     if (url == GURL("https://example.com")) {
-      auto* description = site_info.mutable_description();
-      description->set_name("Example website");
-      description->set_subtitle("Website");
-      description->set_description(
-          "A domain used in illustrative examples in documents.");
-      description->mutable_source()->set_url("https://example.com");
-      description->mutable_source()->set_label("Example source");
+      if (!base::FeatureList::IsEnabled(
+              kPageInfoAboutThisSiteDescriptionPlaceholder)) {
+        auto* description = site_info.mutable_description();
+        description->set_name("Example website");
+        description->set_subtitle("Website");
+        description->set_description(
+            "A domain used in illustrative examples in documents.");
+        description->mutable_source()->set_url("https://example.com");
+        description->mutable_source()->set_label("Example source");
+      }
       site_info.mutable_more_about()->set_url(
           "https://example.com/#more-about");
       return site_info;
@@ -116,6 +136,13 @@
                                 BannerInteraction::kUrlOpened);
 }
 
+// static
+void AboutThisSiteService::OnAboutThisSiteRowClicked(bool with_description) {
+  RecordAboutThisSiteInteraction(
+      with_description ? AboutThisSiteInteraction::kClickedWithDescription
+                       : AboutThisSiteInteraction::kClickedWithoutDescription);
+}
+
 base::WeakPtr<AboutThisSiteService> AboutThisSiteService::GetWeakPtr() {
   return weak_ptr_factory_.GetWeakPtr();
 }
diff --git a/components/page_info/core/about_this_site_service.h b/components/page_info/core/about_this_site_service.h
index 8c2bf0cf..01175d8 100644
--- a/components/page_info/core/about_this_site_service.h
+++ b/components/page_info/core/about_this_site_service.h
@@ -42,6 +42,19 @@
     virtual ~Client() = default;
   };
 
+  // These values are persisted to logs. Entries should not be renumbered and
+  // numeric values should never be reused.
+  // Keep in sync with AboutThisSiteInteraction in enums.xml
+  enum class AboutThisSiteInteraction {
+    kNotShown = 0,
+    kShownWithDescription = 1,
+    kShownWithoutDescription = 2,
+    kClickedWithDescription = 3,
+    kClickedWithoutDescription = 4,
+
+    kMaxValue = kClickedWithoutDescription
+  };
+
   explicit AboutThisSiteService(std::unique_ptr<Client> client);
   ~AboutThisSiteService() override;
 
@@ -57,6 +70,8 @@
   void OnBannerDismissed(GURL url, ukm::SourceId source_id);
   void OnBannerURLOpened(GURL url, ukm::SourceId source_id);
 
+  static void OnAboutThisSiteRowClicked(bool with_description);
+
   base::WeakPtr<AboutThisSiteService> GetWeakPtr();
 
  private:
diff --git a/components/page_info/core/about_this_site_service_unittest.cc b/components/page_info/core/about_this_site_service_unittest.cc
index e314dc3..e8ec1f7 100644
--- a/components/page_info/core/about_this_site_service_unittest.cc
+++ b/components/page_info/core/about_this_site_service_unittest.cc
@@ -22,6 +22,7 @@
 using testing::Return;
 
 using about_this_site_validation::AboutThisSiteStatus;
+using AboutThisSiteInteraction = AboutThisSiteService::AboutThisSiteInteraction;
 using optimization_guide::OptimizationGuideDecision;
 using optimization_guide::OptimizationMetadata;
 
@@ -112,6 +113,8 @@
             "https://google.com/ats/example.com?ctx=chrome");
   t.ExpectUniqueSample("Security.PageInfo.AboutThisSiteStatus",
                        AboutThisSiteStatus::kValid, 1);
+  t.ExpectUniqueSample("Security.PageInfo.AboutThisSiteInteraction",
+                       AboutThisSiteInteraction::kShownWithDescription, 1);
 }
 
 // Tests the language specific feature check.
@@ -135,6 +138,8 @@
   EXPECT_FALSE(info.has_value());
   t.ExpectUniqueSample("Security.PageInfo.AboutThisSiteStatus",
                        AboutThisSiteStatus::kMissingDescriptionSource, 1);
+  t.ExpectUniqueSample("Security.PageInfo.AboutThisSiteInteraction",
+                       AboutThisSiteInteraction::kNotShown, 1);
 }
 
 // Tests that no response is handled.
@@ -148,6 +153,8 @@
   EXPECT_FALSE(info.has_value());
   t.ExpectUniqueSample("Security.PageInfo.AboutThisSiteStatus",
                        AboutThisSiteStatus::kNoResult, 1);
+  t.ExpectUniqueSample("Security.PageInfo.AboutThisSiteInteraction",
+                       AboutThisSiteInteraction::kNotShown, 1);
 }
 
 // Tests that unknown response is handled.
@@ -161,6 +168,8 @@
   EXPECT_FALSE(info.has_value());
   t.ExpectUniqueSample("Security.PageInfo.AboutThisSiteStatus",
                        AboutThisSiteStatus::kUnknown, 1);
+  t.ExpectUniqueSample("Security.PageInfo.AboutThisSiteInteraction",
+                       AboutThisSiteInteraction::kNotShown, 1);
 }
 
 // Tests that banner dismisses are handled.
diff --git a/components/page_info/core/about_this_site_validation.cc b/components/page_info/core/about_this_site_validation.cc
index bba00d4d..aab19f55 100644
--- a/components/page_info/core/about_this_site_validation.cc
+++ b/components/page_info/core/about_this_site_validation.cc
@@ -65,14 +65,20 @@
 }
 
 AboutThisSiteStatus ValidateSiteInfo(const proto::SiteInfo& site_info) {
-  if (!site_info.has_description() && !site_info.has_first_seen())
+  if (!site_info.has_description() && !site_info.has_first_seen() &&
+      !site_info.has_more_about())
     return AboutThisSiteStatus::kEmptySiteInfo;
 
   AboutThisSiteStatus status = AboutThisSiteStatus::kValid;
-  if (!site_info.has_description())
-    return AboutThisSiteStatus::kMissingDescription;
 
-  status = ValidateDescription(site_info.description());
+  if (site_info.has_description()) {
+    status = ValidateDescription(site_info.description());
+  } else {
+    if (!base::FeatureList::IsEnabled(
+            kPageInfoAboutThisSiteDescriptionPlaceholder))
+      return AboutThisSiteStatus::kMissingDescription;
+  }
+
   if (status != AboutThisSiteStatus::kValid)
     return status;
 
diff --git a/components/page_info/core/about_this_site_validation_unittest.cc b/components/page_info/core/about_this_site_validation_unittest.cc
index 1b3802b..2788ace0 100644
--- a/components/page_info/core/about_this_site_validation_unittest.cc
+++ b/components/page_info/core/about_this_site_validation_unittest.cc
@@ -85,13 +85,25 @@
   EXPECT_EQ(ValidateMetadata(metadata), AboutThisSiteStatus::kEmptySiteInfo);
   metadata = GetSampleMetaData();
   metadata.mutable_site_info()->clear_description();
-  EXPECT_EQ(ValidateMetadata(metadata),
-            AboutThisSiteStatus::kMissingDescription);
+  {
+    base::test::ScopedFeatureList features;
+    features.InitAndDisableFeature(
+        kPageInfoAboutThisSiteDescriptionPlaceholder);
+    EXPECT_EQ(ValidateMetadata(metadata),
+              AboutThisSiteStatus::kMissingDescription);
+  }
+
+  {
+    base::test::ScopedFeatureList features;
+    features.InitAndEnableFeature(kPageInfoAboutThisSiteDescriptionPlaceholder);
+    EXPECT_EQ(ValidateMetadata(metadata), AboutThisSiteStatus::kValid);
+  }
 }
 
 TEST(AboutThisSiteValidation, InvalidDescription) {
   proto::SiteDescription description = GetSampleDescription();
   description.clear_description();
+
   EXPECT_EQ(ValidateDescription(description),
             AboutThisSiteStatus::kMissingDescriptionDescription);
 
@@ -111,6 +123,25 @@
             AboutThisSiteStatus::kMissingDescriptionSource);
 }
 
+TEST(AboutThisSiteValidation, OnlyMoreAbout) {
+  proto::SiteInfo site_info;
+  *site_info.mutable_more_about() = GetSampleMoreAbout();
+
+  {
+    base::test::ScopedFeatureList features;
+    features.InitAndDisableFeature(
+        kPageInfoAboutThisSiteDescriptionPlaceholder);
+    EXPECT_EQ(ValidateSiteInfo(site_info),
+              AboutThisSiteStatus::kMissingDescription);
+  }
+
+  {
+    base::test::ScopedFeatureList features;
+    features.InitAndEnableFeature(kPageInfoAboutThisSiteDescriptionPlaceholder);
+    EXPECT_EQ(ValidateSiteInfo(site_info), AboutThisSiteStatus::kValid);
+  }
+}
+
 TEST(AboutThisSiteValidation, InvalidSource) {
   proto::Hyperlink source = GetSampleSource();
   source.clear_label();
diff --git a/components/page_info/core/features.cc b/components/page_info/core/features.cc
index 54c807e..c6b1042f 100644
--- a/components/page_info/core/features.cc
+++ b/components/page_info/core/features.cc
@@ -40,6 +40,10 @@
 const base::Feature kPageInfoAboutThisSiteMoreInfo{
     "PageInfoAboutThisSiteMoreInfo", base::FEATURE_DISABLED_BY_DEFAULT};
 
+const base::Feature kPageInfoAboutThisSiteDescriptionPlaceholder{
+    "PageInfoAboutThisSiteDescriptionPlaceholder",
+    base::FEATURE_DISABLED_BY_DEFAULT};
+
 const base::Feature kAboutThisSiteBanner{"AboutThisSiteBanner",
                                          base::FEATURE_DISABLED_BY_DEFAULT};
 
diff --git a/components/page_info/core/features.h b/components/page_info/core/features.h
index c5bfc690f..439a7af 100644
--- a/components/page_info/core/features.h
+++ b/components/page_info/core/features.h
@@ -37,6 +37,10 @@
 // Shows a link with more info about a site in PageInfo.
 extern const base::Feature kPageInfoAboutThisSiteMoreInfo;
 
+// Shows a placeholder when a description is missing. Only enable in combination
+// with kPageInfoAboutThisSiteMoreInfo.
+extern const base::Feature kPageInfoAboutThisSiteDescriptionPlaceholder;
+
 // Enables the "About this site" banner.
 extern const base::Feature kAboutThisSiteBanner;
 
diff --git a/components/page_info_strings.grdp b/components/page_info_strings.grdp
index c8bbf86..c82984e 100644
--- a/components/page_info_strings.grdp
+++ b/components/page_info_strings.grdp
@@ -695,6 +695,9 @@
   <message name="IDS_PAGE_INFO_ABOUT_THIS_PAGE_TITLE" desc="The title of the 'About this page' row in the Page Info bubble.">
     About this page
   </message>
+  <message name="IDS_PAGE_INFO_ABOUT_THIS_PAGE_DESCRIPTION_PLACEHOLDER" desc="The description of the 'About this page' row in the Page Info bubble if no more detailed description is available. 'It' refers to the page the user is currently visiting.">
+    Learn about its source and topic
+  </message>
   <message name="IDS_PAGE_INFO_ABOUT_THIS_SITE_TOOLTIP" desc="The tooltip of the button that opens 'About this site' subpage in Page Info bubble.">
     Show information from the web
   </message>
diff --git a/components/page_info_strings_grdp/IDS_PAGE_INFO_ABOUT_THIS_PAGE_DESCRIPTION_PLACEHOLDER.png.sha1 b/components/page_info_strings_grdp/IDS_PAGE_INFO_ABOUT_THIS_PAGE_DESCRIPTION_PLACEHOLDER.png.sha1
new file mode 100644
index 0000000..12d05ce
--- /dev/null
+++ b/components/page_info_strings_grdp/IDS_PAGE_INFO_ABOUT_THIS_PAGE_DESCRIPTION_PLACEHOLDER.png.sha1
@@ -0,0 +1 @@
+384e8b0b158aa601a1a42e85eabe82303a90e194
\ No newline at end of file
diff --git a/components/password_manager/ios/BUILD.gn b/components/password_manager/ios/BUILD.gn
index 494bcc4..f8945610 100644
--- a/components/password_manager/ios/BUILD.gn
+++ b/components/password_manager/ios/BUILD.gn
@@ -22,9 +22,11 @@
     "//components/password_manager/core/common",
     "//components/security_state/ios",
     "//components/strings:components_strings_grit",
+    "//components/ukm/ios:ukm_url_recorder",
     "//ios/web/common",
     "//ios/web/public",
     "//ios/web/public/js_messaging",
+    "//services/metrics/public/cpp:ukm_builders",
     "//ui/base",
     "//url",
   ]
@@ -122,10 +124,13 @@
     "//components/password_manager/core/browser",
     "//components/password_manager/core/browser:test_support",
     "//components/password_manager/ios:password_manager_feature",
+    "//components/ukm:test_support",
+    "//components/ukm/ios:ukm_url_recorder",
     "//ios/web/public/js_messaging",
     "//ios/web/public/test",
     "//ios/web/public/test:test_fixture",
     "//ios/web/public/test/fakes",
+    "//services/metrics/public/cpp:ukm_builders",
     "//testing/gmock",
     "//testing/gtest",
     "//third_party/ocmock",
diff --git a/components/password_manager/ios/DEPS b/components/password_manager/ios/DEPS
index 22d68a89..a1fdd578 100644
--- a/components/password_manager/ios/DEPS
+++ b/components/password_manager/ios/DEPS
@@ -4,8 +4,11 @@
   "+components/autofill/ios/browser",
   "+components/autofill/ios/form_util",
   "+components/security_state/ios",
+  "+components/ukm",
+  "+components/ukm/ios",
   "+ios/web/public",
   "+ios/web/common",
+  "+services/metrics/public",
   "+services/network/public/cpp",
   "+third_party/ocmock",
 ]
diff --git a/components/password_manager/ios/password_form_helper.mm b/components/password_manager/ios/password_form_helper.mm
index 97dd82a..b9259eb 100644
--- a/components/password_manager/ios/password_form_helper.mm
+++ b/components/password_manager/ios/password_form_helper.mm
@@ -21,9 +21,11 @@
 #include "components/password_manager/ios/account_select_fill_data.h"
 #include "components/password_manager/ios/password_manager_ios_util.h"
 #import "components/password_manager/ios/password_manager_java_script_feature.h"
+#include "components/ukm/ios/ukm_url_recorder.h"
 #import "ios/web/public/js_messaging/web_frame.h"
 #import "ios/web/public/js_messaging/web_frame_util.h"
 #import "ios/web/public/web_state.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -70,6 +72,9 @@
                 fromJSON:(NSString*)jsonString
                  pageURL:(const GURL&)pageURL;
 
+// Records both UMA & UKM metrics.
+- (void)recordFormFillingSuccessMetrics:(bool)success;
+
 @end
 
 @implementation PasswordFormHelper {
@@ -241,6 +246,18 @@
   }
 }
 
+- (void)recordFormFillingSuccessMetrics:(bool)success {
+  base::UmaHistogramBoolean("PasswordManager.FillingSuccessIOS", success);
+  ukm::SourceId source_id = ukm::GetSourceIdForWebStateDocument(_webState);
+
+  if (source_id == ukm::kInvalidSourceId || !(ukm::UkmRecorder::Get())) {
+    return;
+  }
+  ukm::builders::PasswordManager_PasswordFillingIOS(source_id)
+      .SetFillingSuccess(success)
+      .Record(ukm::UkmRecorder::Get());
+}
+
 #pragma mark - Public methods
 
 - (void)findPasswordFormsWithCompletionHandler:
@@ -283,6 +300,8 @@
           }));
 }
 
+// TODO(crbug.com/1350997): Filling on page load doesn't happen anymore
+// so this method should be deleted.
 - (void)fillPasswordForm:(const autofill::PasswordFormFillData&)formData
                  inFrame:(web::WebFrame*)frame
        completionHandler:(nullable void (^)(BOOL))completionHandler {
@@ -314,18 +333,21 @@
 
   // Send JSON over to the web view.
   __weak PasswordFormHelper* weakSelf = self;
+
   password_manager::PasswordManagerJavaScriptFeature::GetInstance()
       ->FillPasswordForm(mainFrame, formData, UTF16ToUTF8(usernameValue),
                          UTF16ToUTF8(passwordValue),
                          base::BindOnce(^(BOOL success) {
-                           base::UmaHistogramBoolean("PasswordManager."
-                                                     "FillingSuccessIOS",
-                                                     success);
+                           PasswordFormHelper* strongSelf = weakSelf;
+                           if (!strongSelf) {
+                             return;
+                           }
+                           [strongSelf recordFormFillingSuccessMetrics:success];
                            if (success) {
-                             weakSelf.fieldDataManager->UpdateFieldDataMap(
+                             strongSelf.fieldDataManager->UpdateFieldDataMap(
                                  usernameID, usernameValue,
                                  FieldPropertiesFlags::kAutofilledOnPageLoad);
-                             weakSelf.fieldDataManager->UpdateFieldDataMap(
+                             strongSelf.fieldDataManager->UpdateFieldDataMap(
                                  passwordID, passwordValue,
                                  FieldPropertiesFlags::kAutofilledOnPageLoad);
                            }
@@ -395,14 +417,16 @@
       ->FillPasswordForm(
           mainFrame, fillData, fillUsername, UTF16ToUTF8(usernameValue),
           UTF16ToUTF8(passwordValue), base::BindOnce(^(BOOL success) {
-            base::UmaHistogramBoolean("PasswordManager."
-                                      "FillingSuccessIOS",
-                                      success);
+            PasswordFormHelper* strongSelf = weakSelf;
+            if (!strongSelf) {
+              return;
+            }
+            [strongSelf recordFormFillingSuccessMetrics:success];
             if (success) {
-              weakSelf.fieldDataManager->UpdateFieldDataMap(
+              strongSelf.fieldDataManager->UpdateFieldDataMap(
                   usernameID, usernameValue,
                   FieldPropertiesFlags::kAutofilledOnUserTrigger);
-              weakSelf.fieldDataManager->UpdateFieldDataMap(
+              strongSelf.fieldDataManager->UpdateFieldDataMap(
                   passwordID, passwordValue,
                   FieldPropertiesFlags::kAutofilledOnUserTrigger);
             }
diff --git a/components/password_manager/ios/password_form_helper_unittest.mm b/components/password_manager/ios/password_form_helper_unittest.mm
index d497e3d..63df865b 100644
--- a/components/password_manager/ios/password_form_helper_unittest.mm
+++ b/components/password_manager/ios/password_form_helper_unittest.mm
@@ -20,6 +20,8 @@
 #include "components/password_manager/ios/account_select_fill_data.h"
 #include "components/password_manager/ios/password_manager_java_script_feature.h"
 #include "components/password_manager/ios/test_helpers.h"
+#include "components/ukm/ios/ukm_url_recorder.h"
+#include "components/ukm/test_ukm_recorder.h"
 #include "ios/web/public/js_messaging/web_frame_util.h"
 #import "ios/web/public/js_messaging/web_frames_manager.h"
 #import "ios/web/public/test/fakes/fake_navigation_context.h"
@@ -27,6 +29,7 @@
 #import "ios/web/public/test/web_test_with_web_state.h"
 #import "ios/web/public/web_client.h"
 #import "ios/web/public/web_state.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/gtest_mac.h"
 
@@ -68,6 +71,7 @@
     WebTestWithWebState::SetUp();
     UniqueIDDataTabHelper::CreateForWebState(web_state());
     helper_ = [[PasswordFormHelper alloc] initWithWebState:web_state()];
+    ukm::InitializeSourceUrlRecorderForWebState(web_state());
   }
 
   void TearDown() override {
@@ -238,6 +242,7 @@
 
 // Tests that filling password forms with fill data works correctly.
 TEST_F(PasswordFormHelperTest, FillPasswordFormWithFillData) {
+  ukm::TestAutoSetUkmRecorder test_recorder;
   base::HistogramTester histogram_tester;
   LoadHtml(
       @"<form><input id='u1' type='text' name='un1'>"
@@ -267,10 +272,17 @@
 
   histogram_tester.ExpectUniqueSample("PasswordManager.FillingSuccessIOS", true,
                                       1);
+  // Check recorded UKM.
+  auto entries = test_recorder.GetEntriesByName(
+      ukm::builders::PasswordManager_PasswordFillingIOS::kEntryName);
+  // Expect one recorded metric.
+  ASSERT_EQ(1u, entries.size());
+  test_recorder.ExpectEntryMetric(entries[0], "FillingSuccess", true);
 }
 
 // Tests that failure in filling password forms with fill data is recorded.
 TEST_F(PasswordFormHelperTest, FillPasswordFormWithFillDataFillingFailure) {
+  ukm::TestAutoSetUkmRecorder test_recorder;
   base::HistogramTester histogram_tester;
   LoadHtml(@"<form><input id='u1' type='text' name='un1'>"
             "<input id='p1' type='password' name='pw1'></form>");
@@ -297,11 +309,18 @@
 
   histogram_tester.ExpectUniqueSample("PasswordManager.FillingSuccessIOS",
                                       false, 1);
+  // Check recorded UKM.
+  auto entries = test_recorder.GetEntriesByName(
+      ukm::builders::PasswordManager_PasswordFillingIOS::kEntryName);
+  // Expect one recorded metric.
+  ASSERT_EQ(1u, entries.size());
+  test_recorder.ExpectEntryMetric(entries[0], "FillingSuccess", false);
 }
 
 // Tests that a form is found and the found form is filled in with the given
 // username and password.
 TEST_F(PasswordFormHelperTest, FindAndFillOnePasswordForm) {
+  ukm::TestAutoSetUkmRecorder test_recorder;
   base::HistogramTester histogram_tester;
   LoadHtml(
       @"<form><input id='u1' type='text' name='un1'>"
@@ -332,11 +351,18 @@
   EXPECT_NSEQ(@"u1=john.doe@gmail.com;p1=super!secret;", result);
   histogram_tester.ExpectUniqueSample("PasswordManager.FillingSuccessIOS", true,
                                       1);
+  // Check recorded UKM.
+  auto entries = test_recorder.GetEntriesByName(
+      ukm::builders::PasswordManager_PasswordFillingIOS::kEntryName);
+  // Expect one recorded metric.
+  ASSERT_EQ(1u, entries.size());
+  test_recorder.ExpectEntryMetric(entries[0], "FillingSuccess", true);
 }
 
 // Tests that failure in filling password form with the given
 // username and password is recorded.
 TEST_F(PasswordFormHelperTest, FindAndFillOnePasswordFormFillingFailure) {
+  ukm::TestAutoSetUkmRecorder test_recorder;
   base::HistogramTester histogram_tester;
   LoadHtml(@"<form><input id='u1' type='text' name='un1'>"
             "<input id='p1' type='password' name='pw1'></form>");
@@ -360,6 +386,12 @@
   }));
   histogram_tester.ExpectUniqueSample("PasswordManager.FillingSuccessIOS",
                                       false, 1);
+  // Check recorded UKM.
+  auto entries = test_recorder.GetEntriesByName(
+      ukm::builders::PasswordManager_PasswordFillingIOS::kEntryName);
+  // Expect one recorded metric.
+  ASSERT_EQ(1u, entries.size());
+  test_recorder.ExpectEntryMetric(entries[0], "FillingSuccess", false);
 }
 
 // Tests that extractPasswordFormData extracts wanted form on page with mutiple
diff --git a/content/browser/accessibility/browser_accessibility_com_win.cc b/content/browser/accessibility/browser_accessibility_com_win.cc
index 9cadc49..d6a00de6 100644
--- a/content/browser/accessibility/browser_accessibility_com_win.cc
+++ b/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -698,11 +698,6 @@
   if (action_index < 0 || action_index >= static_cast<LONG>(actions.size()))
     return E_INVALIDARG;
 
-  if (action_index == 0 && owner()->HasDefaultActionVerb()) {
-    // If there is a default action, it will always be at index 0.
-    Manager()->DoDefaultAction(*owner());
-    return S_OK;
-  }
   ui::AXActionData data;
   data.action = actions[action_index];
   owner()->AccessibilityPerformAction(data);
diff --git a/content/browser/preloading/prerender/prerender_host.cc b/content/browser/preloading/prerender/prerender_host.cc
index b6b36e1..ce51338 100644
--- a/content/browser/preloading/prerender/prerender_host.cc
+++ b/content/browser/preloading/prerender/prerender_host.cc
@@ -71,8 +71,8 @@
 
 PrerenderHost::PrerenderHost(const PrerenderAttributes& attributes,
                              WebContents& web_contents,
-                             PreloadingAttemptImpl* attempt)
-    : attributes_(attributes), attempt_(attempt) {
+                             base::WeakPtr<PreloadingAttempt> attempt)
+    : attributes_(attributes), attempt_(std::move(attempt)) {
   DCHECK(blink::features::IsPrerender2Enabled());
   // If the prerendering is browser-initiated, it is expected to have no
   // initiator. All initiator related information should be null or invalid. On
diff --git a/content/browser/preloading/prerender/prerender_host.h b/content/browser/preloading/prerender/prerender_host.h
index 64fab8f9..b32ffcd 100644
--- a/content/browser/preloading/prerender/prerender_host.h
+++ b/content/browser/preloading/prerender/prerender_host.h
@@ -100,7 +100,7 @@
 
   PrerenderHost(const PrerenderAttributes& attributes,
                 WebContents& web_contents,
-                PreloadingAttemptImpl* attempt);
+                base::WeakPtr<PreloadingAttempt> attempt);
   ~PrerenderHost() override;
 
   PrerenderHost(const PrerenderHost&) = delete;
@@ -240,8 +240,9 @@
   base::ObserverList<Observer> observers_;
 
   // Stores the attempt corresponding to this prerender to log various metrics.
-  raw_ptr<PreloadingAttemptImpl, DanglingUntriaged> attempt_;
-
+  // We use a WeakPtr here to avoid inadvertent UAF. `attempt_` can get deleted
+  // before `PrerenderHostRegistry::DeleteAbandonedHosts` is scheduled.
+  base::WeakPtr<PreloadingAttempt> attempt_;
   // Navigation parameters for the navigation which loaded the main document of
   // the prerendered page, copied immediately after BeginNavigation when
   // throttles are created. They will be compared with the navigation parameters
diff --git a/content/browser/preloading/prerender/prerender_host_registry.cc b/content/browser/preloading/prerender/prerender_host_registry.cc
index 763d371..56b1da6e 100644
--- a/content/browser/preloading/prerender/prerender_host_registry.cc
+++ b/content/browser/preloading/prerender/prerender_host_registry.cc
@@ -181,9 +181,8 @@
       return RenderFrameHost::kNoFrameTreeNodeId;
     }
 
-    auto* attempt_impl = static_cast<PreloadingAttemptImpl*>(attempt);
-    auto prerender_host =
-        std::make_unique<PrerenderHost>(attributes, web_contents, attempt_impl);
+    auto prerender_host = std::make_unique<PrerenderHost>(
+        attributes, web_contents, attempt ? attempt->GetWeakPtr() : nullptr);
     frame_tree_node_id = prerender_host->frame_tree_node_id();
 
     CHECK(!base::Contains(prerender_host_by_frame_tree_node_id_,
diff --git a/content/browser/webui/web_ui_unittest.cc b/content/browser/webui/web_ui_unittest.cc
index 3fe944f..18af9058 100644
--- a/content/browser/webui/web_ui_unittest.cc
+++ b/content/browser/webui/web_ui_unittest.cc
@@ -30,10 +30,9 @@
 TEST_F(WebUITest, TestHandler) {
   web_ui_->RegisterHandlerCallback("testMessage",
                                    base::BindRepeating(&HandleTestMessage));
-  base::Value args(base::Value::Type::LIST);
+  base::Value::List args;
   args.Append(11);
   args.Append(true);
   args.Append("test text");
-  web_ui_->HandleReceivedMessage("testMessage",
-                                 &base::Value::AsListValue(args));
+  web_ui_->HandleReceivedMessage("testMessage", args);
 }
diff --git a/content/public/test/test_web_ui.cc b/content/public/test/test_web_ui.cc
index 5c3d5be4..5b309847 100644
--- a/content/public/test/test_web_ui.cc
+++ b/content/public/test/test_web_ui.cc
@@ -39,11 +39,6 @@
   }
 }
 
-void TestWebUI::HandleReceivedMessage(const std::string& handler_name,
-                                      const base::ListValue* args) {
-  HandleReceivedMessage(handler_name, args->GetList());
-}
-
 WebContents* TestWebUI::GetWebContents() {
   return web_contents_;
 }
diff --git a/content/public/test/test_web_ui.h b/content/public/test/test_web_ui.h
index f8a6e01..03f6dbd 100644
--- a/content/public/test/test_web_ui.h
+++ b/content/public/test/test_web_ui.h
@@ -31,10 +31,7 @@
   void ClearTrackedCalls();
   void HandleReceivedMessage(const std::string& handler_name,
                              const base::Value::List& args);
-  // TODO(crbug.com/1187062): Remove this HandleReceivedMessage() variant and
-  // switch to the one above.
-  void HandleReceivedMessage(const std::string& handler_name,
-                             const base::ListValue* args);
+
   void set_web_contents(WebContents* web_contents) {
     web_contents_ = web_contents;
   }
diff --git a/ios/chrome/browser/net/cookies_egtest.mm b/ios/chrome/browser/net/cookies_egtest.mm
index 7c769d7..ef535e3 100644
--- a/ios/chrome/browser/net/cookies_egtest.mm
+++ b/ios/chrome/browser/net/cookies_egtest.mm
@@ -130,6 +130,9 @@
 // incognito tabs and then when new incognito tab is created the cookie will
 // not reappear.
 - (void)testClearIncognitoFromIncognito {
+  // TODO(crbug.com/1352084): Fix flakiness.
+  EARL_GREY_TEST_DISABLED(@"Test is flaky.")
+
   // Loads a page in normal tab.
   [ChromeEarlGrey loadURL:self.testServer->GetURL("/echo")];
 
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm
index 42615c6..1eb4d05 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/password_view_controller_egtest.mm
@@ -127,6 +127,11 @@
 // Tests that the passwords view controller contains the "Manage Passwords..."
 // action.
 - (void)testPasswordsViewControllerContainsManagePasswordsAction {
+  // TODO(crbug.com/1352059): Re-enable when flake fixed.
+  if ([ChromeEarlGrey isIPadIdiom]) {
+    EARL_GREY_TEST_DISABLED(@"Test flaky failing on iPad.")
+  }
+
   // Bring up the keyboard.
   [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
       performAction:TapWebElementWithId(kFormElementUsername)];
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
index 65c5bebf..51379a1 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
@@ -390,9 +390,8 @@
 // Validates this case when Tab Grid Bulk Actions feature is enabled.
 - (void)testCloseAllAndUndoCloseAll {
   // TODO(crbug.com/1350734): Re-enable when flake fixed.
-  if (@available(iOS 16, *)) {
-    EARL_GREY_TEST_DISABLED(@"Test consistently failing on iOS16 iPhone 8.")
-  }
+  EARL_GREY_TEST_DISABLED(
+      @"Test consistently failing on iOS16 iPhone 8 and flaky on others.")
 
   [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
       performAction:grey_tap()];
diff --git a/media/base/user_input_monitor_linux.cc b/media/base/user_input_monitor_linux.cc
index 8ff8a1f..4aabec94 100644
--- a/media/base/user_input_monitor_linux.cc
+++ b/media/base/user_input_monitor_linux.cc
@@ -97,7 +97,7 @@
   void StopKeyboardMonitoring() override;
 
   scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
-  raw_ptr<UserInputMonitorAdapter, DanglingUntriaged> core_;
+  raw_ptr<UserInputMonitorAdapter> core_;
 };
 
 UserInputMonitorAdapter* CreateUserInputMonitor(
@@ -117,8 +117,8 @@
       core_(CreateUserInputMonitor(io_task_runner_)) {}
 
 UserInputMonitorLinux::~UserInputMonitorLinux() {
-  if (core_ && !io_task_runner_->DeleteSoon(FROM_HERE, core_.get()))
-    delete core_;
+  if (!io_task_runner_->DeleteSoon(FROM_HERE, core_.get()))
+    core_.ClearAndDelete();
 }
 
 uint32_t UserInputMonitorLinux::GetKeyPressCount() const {
diff --git a/remoting/codec/webrtc_video_encoder_av1.cc b/remoting/codec/webrtc_video_encoder_av1.cc
index cc1bceb..fa3df8c 100644
--- a/remoting/codec/webrtc_video_encoder_av1.cc
+++ b/remoting/codec/webrtc_video_encoder_av1.cc
@@ -10,6 +10,7 @@
 #include "base/system/sys_info.h"
 #include "remoting/base/cpu_utils.h"
 #include "remoting/base/util.h"
+#include "third_party/libaom/source/libaom/aom/aomcx.h"
 #include "third_party/libyuv/include/libyuv/convert_from_argb.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
@@ -74,6 +75,10 @@
   }
   DCHECK_NE(codec->name, nullptr);
 
+  if (use_active_map_) {
+    active_map_.Initialize(size);
+  }
+
   error = aom_codec_control(codec.get(), AOME_SET_CPUUSED, 10);
   DCHECK_EQ(error, AOM_CODEC_OK) << "Failed to set AOME_SET_CPUUSED";
 
@@ -171,12 +176,14 @@
   return true;
 }
 
-void WebrtcVideoEncoderAV1::PrepareImage(const webrtc::DesktopFrame* frame) {
+void WebrtcVideoEncoderAV1::PrepareImage(
+    const webrtc::DesktopFrame* frame,
+    webrtc::DesktopRegion& updated_region) {
+  updated_region.Clear();
   if (!frame) {
     return;
   }
 
-  webrtc::DesktopRegion updated_region;
   if (image_) {
     DCHECK_EQ(frame->size().width(), static_cast<int>(image_->d_w));
     DCHECK_EQ(frame->size().height(), static_cast<int>(image_->d_h));
@@ -329,7 +336,27 @@
 
   // Transfer the frame data to the image buffer for encoding.
   // TODO(joedow): Look into using aom_img_wrap instead of our own buffer.
-  PrepareImage(frame.get());
+  webrtc::DesktopRegion updated_region;
+  PrepareImage(frame.get(), updated_region);
+
+  aom_active_map_t act_map;
+  if (use_active_map_) {
+    if (params.clear_active_map)
+      active_map_.Clear();
+
+    if (params.key_frame)
+      updated_region.SetRect(webrtc::DesktopRect::MakeSize(frame_size));
+
+    active_map_.Update(updated_region);
+
+    // Apply active map to the encoder.
+    act_map.rows = active_map_.height();
+    act_map.cols = active_map_.width();
+    act_map.active_map = active_map_.data();
+    if (aom_codec_control(codec_.get(), AOME_SET_ACTIVEMAP, &act_map)) {
+      LOG(ERROR) << "Unable to apply active map";
+    }
+  }
 
   auto duration_us = params.duration.InMicroseconds();
   DCHECK_GT(duration_us, 0);
@@ -346,6 +373,14 @@
     return;
   }
 
+  if (use_active_map_) {
+    // Update our active map based on the internal map in the encoder.
+    ret = aom_codec_control(codec_.get(), AV1E_GET_ACTIVEMAP, &act_map);
+    DCHECK_EQ(ret, AOM_CODEC_OK)
+        << "Failed to fetch active map: " << aom_codec_err_to_string(ret)
+        << "\n";
+  }
+
   // Read the encoded data.
   aom_codec_iter_t iter = nullptr;
   bool got_data = false;
diff --git a/remoting/codec/webrtc_video_encoder_av1.h b/remoting/codec/webrtc_video_encoder_av1.h
index abb7970..b4b454fa 100644
--- a/remoting/codec/webrtc_video_encoder_av1.h
+++ b/remoting/codec/webrtc_video_encoder_av1.h
@@ -7,11 +7,18 @@
 
 #include "base/callback.h"
 #include "remoting/codec/encoder_bitrate_filter.h"
+#include "remoting/codec/video_encoder_active_map.h"
 #include "remoting/codec/webrtc_video_encoder.h"
 #include "third_party/libaom/source/libaom/aom/aom_encoder.h"
 #include "third_party/libaom/source/libaom/aom/aom_image.h"
 #include "third_party/libaom/source/libaom/aom/aomcx.h"
 
+namespace webrtc {
+class DesktopFrame;
+class DesktopRegion;
+class DesktopSize;
+}  // namespace webrtc
+
 namespace remoting {
 
 // AV1 encoder implementation for WebRTC transport, params are optimized for
@@ -34,7 +41,8 @@
   void ConfigureCodecParams();
   bool InitializeCodec(const webrtc::DesktopSize& size);
   void UpdateConfig(const FrameParams& params);
-  void PrepareImage(const webrtc::DesktopFrame* frame);
+  void PrepareImage(const webrtc::DesktopFrame* frame,
+                    webrtc::DesktopRegion& updated_region);
 
   using scoped_aom_codec =
       std::unique_ptr<aom_codec_ctx_t, void (*)(aom_codec_ctx_t*)>;
@@ -45,6 +53,11 @@
   using scoped_aom_image = std::unique_ptr<aom_image_t, void (*)(aom_image_t*)>;
   scoped_aom_image image_;
 
+  // Active map used to optimize out processing of unchanged macroblocks.
+  VideoEncoderActiveMap active_map_;
+  // Disable |active_map_| until we've verified it improves performance.
+  const bool use_active_map_ = false;
+
   // This timestamp is monotonically increased using the current frame duration.
   // It's only used for rate control and is not related to the timestamps on the
   // incoming frames to encode.
diff --git a/storage/browser/file_system/obfuscated_file_util.cc b/storage/browser/file_system/obfuscated_file_util.cc
index 15fde18..2c692cf 100644
--- a/storage/browser/file_system/obfuscated_file_util.cc
+++ b/storage/browser/file_system/obfuscated_file_util.cc
@@ -147,15 +147,6 @@
 
 // end DatabaseKey implementation.
 
-// TODO(https://crbug.com/1248104): This class will eventually interface with
-// Storage Buckets instead of directly interfacing with LevelDB. Thus, the below
-// functions were converted from url::Origin to blink::StorageKey to prepare for
-// Storage Partitioning of the FileSystem APIs. However, it is important to note
-// that, until the refactor to use Storage Buckets, the LevelDB structure above
-// is still used, and the entries are still keyed per-origin (achieved by
-// storage_key.origin()) and per-type. Going forward, OriginRecords will be
-// retrieved from the database and converted into StorageKey values until
-// Storage Buckets are implemented instead.
 class ObfuscatedFileEnumerator final
     : public FileSystemFileUtil::AbstractFileEnumerator {
  public:
@@ -254,6 +245,14 @@
   base::File::Info current_platform_file_info_;
 };
 
+// NOTE: currently, ObfuscatedFileUtil still relies on SandboxOriginDatabases
+// for first-party StorageKeys/default buckets. The AbstractStorageKeyEnumerator
+// class is only used in these cases. While this class stores and iterates
+// through StorageKeys types, it works by retrieving OriginRecords from the
+// SandboxOriginDatabase and converting those origins into first-party
+// StorageKey values (e.g. blink::StorageKey(origin)). The goal is to eventually
+// deprecate SandboxOriginDatabases and AbstractStorageKeyEnumerators and rely
+// entirely on Storage Buckets.
 class ObfuscatedStorageKeyEnumerator
     : public ObfuscatedFileUtil::AbstractStorageKeyEnumerator {
  public:
diff --git a/storage/browser/file_system/obfuscated_file_util.h b/storage/browser/file_system/obfuscated_file_util.h
index d1354e5..4b13568 100644
--- a/storage/browser/file_system/obfuscated_file_util.h
+++ b/storage/browser/file_system/obfuscated_file_util.h
@@ -83,20 +83,27 @@
   std::string type_;
 };
 
-// This file util stores directory information in LevelDB to obfuscate
-// and to neutralize virtual file paths given by arbitrary apps.
-// Files are stored with two-level isolation: per-origin and per-type.
-// The isolation is done by storing data in separate directory partitions.
-// For example, a file in Temporary file system for origin 'www.example.com'
-// is stored in a different partition for a file in Persistent file system
-// for the same origin, or for Temporary file system for another origin.
+// This file util stores directory information in either LevelDB or
+// StorageBuckets to obfuscate and to neutralize virtual file paths given by
+// arbitrary apps. Files are stored with three-level isolation: (1)
+// per-StorageKey, (2) per-bucket, and (3) per-type. The isolation is done by
+// storing data in separate directory partitions. For example, a file in
+// Temporary file system for origin 'www.example.com' is stored in a different
+// partition from a file in Persistent file system for the same origin, or from
+// a file in a Temporary file system for another origin. Similarly, a file in a
+// Temporary file system for origin 'www.foo.com' with a default bucket is
+// stored in a different partition from a non-default bucket for the same origin
+// and Temporary file system.
 //
-// * Per-origin directory name information is stored in a separate LevelDB,
-//   which is maintained by SandboxOriginDatabase.
-// * Per-type directory name information is given by
-//   GetTypeStringForURLCallback that is given in CTOR.
-//   We use a small static mapping (e.g. 't' for Temporary type) for
-//   regular sandbox filesystems.
+// * For default first-party StorageKeys, per-origin directory name information
+//   is stored in a separate LevelDB, which is maintained by
+//   SandboxOriginDatabase. For per-type information, we use a small static
+//   mapping (e.g. 't' for Temporary type) for regular sandbox filesystems.
+//   NOTE/TODO(https://crbug.com/1349156): the goal is to eventually deprecate
+//   SandboxOriginDatabase and rely entirely on Storage Buckets.
+// * For all other StorageKeys, we rely on quota management of Storage Buckets
+//   in addition to the same static mapping of per-type information described
+//   above.
 //
 // The overall implementation philosophy of this class is that partial failures
 // should leave us with an intact database; we'd prefer to leak the occasional
@@ -106,21 +113,16 @@
 //
 // This class must be deleted on the FILE thread, because that's where
 // DropDatabases needs to be called.
-//
-// TODO(https://crbug.com/1248104): This class will eventually use Storage
-// Buckets instead of LevelDB. Thus, the below functions were converted from
-// url::Origin to blink::StorageKey to prepare for Storage Partitioning of the
-// FileSystem APIs. However, it is important to note that, until the refactor to
-// use Storage Buckets, the LevelDB structure above is still used, and the
-// entries are still keyed per-origin (achieved by storage_key.origin()) and
-// per-type. Going forward, comments will refer to the DB as "origin database"
-// or the directory as "origin directory", but the origin will come from a
-// larger StorageKey object.
 class COMPONENT_EXPORT(STORAGE_BROWSER) ObfuscatedFileUtil
     : public FileSystemFileUtil {
  public:
   // StorageKey enumerator interface.
   // An instance of this interface is assumed to be called on the file thread.
+  // NOTE: currently, ObfuscatedFileUtil still relies on SandboxOriginDatabases
+  // for first-party StorageKeys/default buckets. The
+  // AbstractStorageKeyEnumerator is only used in these cases. While this class
+  // stores StorageKeys, it ultimately relies on only the origin information to
+  // access the appropriate SandboxOriginDatabase.
   class AbstractStorageKeyEnumerator {
    public:
     virtual ~AbstractStorageKeyEnumerator() = default;
@@ -129,21 +131,20 @@
     // StorageKeys.
     virtual absl::optional<blink::StorageKey> Next() = 0;
 
-    // Returns the current origin's information.
+    // Returns the current StorageKey's information.
     // `type_string` must be ascii string.
     virtual bool HasTypeDirectory(const std::string& type_string) const = 0;
   };
 
-  using GetTypeStringForURLCallback =
-      base::RepeatingCallback<std::string(const FileSystemURL&)>;
-
   // The type string is used to provide per-type isolation in the sandboxed
   // filesystem directory. `known_type_strings` are known type string names that
   // this file system should care about. This info is used to determine whether
   // we could delete the entire origin directory or not in
   // DeleteDirectoryForStorageKeyAndType. If no directory for any known type
   // exists the origin directory may get deleted when one StorageKey/type pair
-  // is deleted.
+  // is deleted. NOTE: type strings are not mapped 1-to-1 with FileSystemType,
+  // and as a result, directories should only be directly compared using type
+  // string values.
   ObfuscatedFileUtil(scoped_refptr<SpecialStoragePolicy> special_storage_policy,
                      const base::FilePath& file_system_directory,
                      leveldb::Env* env_override,
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 974340d..3c91fb1 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -5753,21 +5753,21 @@
       {
         "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_v106.0.5231.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5232.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5231.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5232.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v106.0.5231.0",
-              "revision": "version:106.0.5231.0"
+              "location": "lacros_version_skew_tests_v106.0.5232.0",
+              "revision": "version:106.0.5232.0"
             }
           ],
           "dimension_sets": [
@@ -5780,7 +5780,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5231.0"
+        "variant_id": "Lacros version skew testing ash 106.0.5232.0"
       },
       {
         "isolate_profile_data": true,
@@ -5918,21 +5918,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5231.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5232.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5231.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5232.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v106.0.5231.0",
-              "revision": "version:106.0.5231.0"
+              "location": "lacros_version_skew_tests_v106.0.5232.0",
+              "revision": "version:106.0.5232.0"
             }
           ],
           "dimension_sets": [
@@ -5944,7 +5944,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5231.0"
+        "variant_id": "Lacros version skew testing ash 106.0.5232.0"
       },
       {
         "args": [
@@ -6064,21 +6064,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5231.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5232.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5231.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5232.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v106.0.5231.0",
-              "revision": "version:106.0.5231.0"
+              "location": "lacros_version_skew_tests_v106.0.5232.0",
+              "revision": "version:106.0.5232.0"
             }
           ],
           "dimension_sets": [
@@ -6090,7 +6090,7 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 106.0.5231.0"
+        "variant_id": "Lacros version skew testing ash 106.0.5232.0"
       },
       {
         "isolate_profile_data": true,
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index c706bea4..f104a36b 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -99293,21 +99293,21 @@
       {
         "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_v106.0.5231.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5232.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5231.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5232.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v106.0.5231.0",
-              "revision": "version:106.0.5231.0"
+              "location": "lacros_version_skew_tests_v106.0.5232.0",
+              "revision": "version:106.0.5232.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -99315,7 +99315,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5231.0"
+        "variant_id": "Lacros version skew testing ash 106.0.5232.0"
       },
       {
         "isolate_profile_data": true,
@@ -99428,28 +99428,28 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5231.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5232.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5231.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5232.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v106.0.5231.0",
-              "revision": "version:106.0.5231.0"
+              "location": "lacros_version_skew_tests_v106.0.5232.0",
+              "revision": "version:106.0.5232.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5231.0"
+        "variant_id": "Lacros version skew testing ash 106.0.5232.0"
       },
       {
         "args": [
@@ -99549,28 +99549,28 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5231.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5232.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5231.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5232.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v106.0.5231.0",
-              "revision": "version:106.0.5231.0"
+              "location": "lacros_version_skew_tests_v106.0.5232.0",
+              "revision": "version:106.0.5232.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 106.0.5231.0"
+        "variant_id": "Lacros version skew testing ash 106.0.5232.0"
       },
       {
         "isolate_profile_data": true,
@@ -100908,20 +100908,20 @@
       {
         "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_v106.0.5231.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5232.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5231.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5232.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v106.0.5231.0",
-              "revision": "version:106.0.5231.0"
+              "location": "lacros_version_skew_tests_v106.0.5232.0",
+              "revision": "version:106.0.5232.0"
             }
           ],
           "dimension_sets": [
@@ -100935,7 +100935,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5231.0"
+        "variant_id": "Lacros version skew testing ash 106.0.5232.0"
       },
       {
         "merge": {
@@ -101073,20 +101073,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5231.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5232.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5231.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5232.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v106.0.5231.0",
-              "revision": "version:106.0.5231.0"
+              "location": "lacros_version_skew_tests_v106.0.5232.0",
+              "revision": "version:106.0.5232.0"
             }
           ],
           "dimension_sets": [
@@ -101099,7 +101099,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5231.0"
+        "variant_id": "Lacros version skew testing ash 106.0.5232.0"
       },
       {
         "args": [
@@ -101219,20 +101219,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5231.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5232.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5231.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5232.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v106.0.5231.0",
-              "revision": "version:106.0.5231.0"
+              "location": "lacros_version_skew_tests_v106.0.5232.0",
+              "revision": "version:106.0.5232.0"
             }
           ],
           "dimension_sets": [
@@ -101245,7 +101245,7 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 106.0.5231.0"
+        "variant_id": "Lacros version skew testing ash 106.0.5232.0"
       },
       {
         "merge": {
@@ -102741,20 +102741,20 @@
       {
         "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_v106.0.5231.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5232.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5231.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5232.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v106.0.5231.0",
-              "revision": "version:106.0.5231.0"
+              "location": "lacros_version_skew_tests_v106.0.5232.0",
+              "revision": "version:106.0.5232.0"
             }
           ],
           "dimension_sets": [
@@ -102768,7 +102768,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5231.0"
+        "variant_id": "Lacros version skew testing ash 106.0.5232.0"
       },
       {
         "merge": {
@@ -102906,20 +102906,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5231.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5232.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5231.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5232.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v106.0.5231.0",
-              "revision": "version:106.0.5231.0"
+              "location": "lacros_version_skew_tests_v106.0.5232.0",
+              "revision": "version:106.0.5232.0"
             }
           ],
           "dimension_sets": [
@@ -102932,7 +102932,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5231.0"
+        "variant_id": "Lacros version skew testing ash 106.0.5232.0"
       },
       {
         "args": [
@@ -103052,20 +103052,20 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5231.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5232.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5231.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5232.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v106.0.5231.0",
-              "revision": "version:106.0.5231.0"
+              "location": "lacros_version_skew_tests_v106.0.5232.0",
+              "revision": "version:106.0.5232.0"
             }
           ],
           "dimension_sets": [
@@ -103078,7 +103078,7 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 106.0.5231.0"
+        "variant_id": "Lacros version skew testing ash 106.0.5232.0"
       },
       {
         "merge": {
@@ -103813,20 +103813,20 @@
       {
         "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_v106.0.5231.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5232.0/test_ash_chrome"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5231.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5232.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v106.0.5231.0",
-              "revision": "version:106.0.5231.0"
+              "location": "lacros_version_skew_tests_v106.0.5232.0",
+              "revision": "version:106.0.5232.0"
             }
           ],
           "dimension_sets": [
@@ -103839,7 +103839,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5231.0"
+        "variant_id": "Lacros version skew testing ash 106.0.5232.0"
       }
     ]
   },
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index f307b28..7b5944e8 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -20871,21 +20871,21 @@
       {
         "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_v106.0.5231.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5232.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5231.0",
+        "name": "interactive_ui_tests Lacros version skew testing ash 106.0.5232.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v106.0.5231.0",
-              "revision": "version:106.0.5231.0"
+              "location": "lacros_version_skew_tests_v106.0.5232.0",
+              "revision": "version:106.0.5232.0"
             }
           ],
           "dimension_sets": [
@@ -20898,7 +20898,7 @@
         },
         "test": "interactive_ui_tests",
         "test_id_prefix": "ninja://chrome/test:interactive_ui_tests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5231.0"
+        "variant_id": "Lacros version skew testing ash 106.0.5232.0"
       },
       {
         "isolate_profile_data": true,
@@ -21036,21 +21036,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5231.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5232.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5231.0",
+        "name": "lacros_chrome_browsertests Lacros version skew testing ash 106.0.5232.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v106.0.5231.0",
-              "revision": "version:106.0.5231.0"
+              "location": "lacros_version_skew_tests_v106.0.5232.0",
+              "revision": "version:106.0.5232.0"
             }
           ],
           "dimension_sets": [
@@ -21062,7 +21062,7 @@
         },
         "test": "lacros_chrome_browsertests",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/",
-        "variant_id": "Lacros version skew testing ash 106.0.5231.0"
+        "variant_id": "Lacros version skew testing ash 106.0.5232.0"
       },
       {
         "args": [
@@ -21182,21 +21182,21 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5231.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5232.0/test_ash_chrome"
         ],
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5231.0",
+        "name": "lacros_chrome_browsertests_run_in_series Lacros version skew testing ash 106.0.5232.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v106.0.5231.0",
-              "revision": "version:106.0.5231.0"
+              "location": "lacros_version_skew_tests_v106.0.5232.0",
+              "revision": "version:106.0.5232.0"
             }
           ],
           "dimension_sets": [
@@ -21208,7 +21208,7 @@
         },
         "test": "lacros_chrome_browsertests_run_in_series",
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests_run_in_series/",
-        "variant_id": "Lacros version skew testing ash 106.0.5231.0"
+        "variant_id": "Lacros version skew testing ash 106.0.5232.0"
       },
       {
         "isolate_profile_data": true,
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 5480450..66f02e9 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -22,15 +22,15 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5231.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v106.0.5232.0/test_ash_chrome',
     ],
-    'identifier': 'Lacros version skew testing ash 106.0.5231.0',
+    'identifier': 'Lacros version skew testing ash 106.0.5232.0',
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v106.0.5231.0',
-          'revision': 'version:106.0.5231.0',
+          'location': 'lacros_version_skew_tests_v106.0.5232.0',
+          'revision': 'version:106.0.5232.0',
         },
       ],
     },
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 3400b719..a41c521 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -332,6 +332,21 @@
             ]
         }
     ],
+    "AndroidPermissionsCache": [
+        {
+            "platforms": [
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "AndroidPermissionsCache"
+                    ]
+                }
+            ]
+        }
+    ],
     "AndroidPhotoPickerComparison": [
         {
             "platforms": [
@@ -3719,6 +3734,21 @@
             ]
         }
     ],
+    "DifferentWorkQueueCapacities": [
+        {
+            "platforms": [
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "DifferentWorkQueueCapacities"
+                    ]
+                }
+            ]
+        }
+    ],
     "DisableCompositedProgressBar": [
         {
             "platforms": [
@@ -6407,7 +6437,7 @@
                         "EntitySuggestionsReduceLatencyDecoderTimeout": "405",
                         "MaxZeroSuggestMatches": "10",
                         "OmniboxBookmarkPathsUiDynamicReplaceUrl": "true",
-                        "OmniboxLocalZeroSuggestAgeThreshold": "60",
+                        "OmniboxLocalZeroSuggestAgeThreshold": "90",
                         "OmniboxMaxURLMatches": "7",
                         "PrefixSuggestIgnoreDuplicateVisits": "true",
                         "ShortBookmarkSuggestionsByTotalInputLengthThreshold": "3",
@@ -6443,7 +6473,7 @@
                     "name": "AndroidExperiments",
                     "params": {
                         "OmniboxDynamicMaxAutocompleteIncreasedLimit": "15",
-                        "OmniboxLocalZeroSuggestAgeThreshold": "30",
+                        "OmniboxLocalZeroSuggestAgeThreshold": "90",
                         "OmniboxMaxURLMatches": "8",
                         "UIMaxAutocompleteMatches": "10"
                     },
@@ -6471,10 +6501,13 @@
                 {
                     "name": "IOSExperiments",
                     "params": {
-                        "MaxZeroSuggestMatches": "20"
+                        "MaxZeroSuggestMatches": "20",
+                        "OmniboxLocalZeroSuggestAgeThreshold": "90"
                     },
                     "enable_features": [
-                        "OmniboxMaxZeroSuggestMatches"
+                        "OmniboxLocalZeroSuggestAgeThreshold",
+                        "OmniboxMaxZeroSuggestMatches",
+                        "ZeroSuggestPrefetching"
                     ]
                 }
             ]
@@ -9314,6 +9347,21 @@
             ]
         }
     ],
+    "ToolbarPhoneOptimizations": [
+        {
+            "platforms": [
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "ToolbarPhoneOptimizations"
+                    ]
+                }
+            ]
+        }
+    ],
     "TouchToFillPasswordSubmissionStudy": [
         {
             "platforms": [
diff --git a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
index 964a9a3..f8dcfd8 100644
--- a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
+++ b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
@@ -3647,6 +3647,7 @@
   kV8PendingPostBeacon_Constructor = 4326,
   kV8PendingPostBeacon_SetData_Method = 4327,
   kContentVisibilityAutoStateChangedHandlerRegistered = 4328,
+  kReplacedElementPaintedWithLargeOverflow = 4329,
 
   // Add new features immediately above this line. Don't change assigned
   // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/renderer/bindings/BUILD.gn b/third_party/blink/renderer/bindings/BUILD.gn
index ea07f5b..c468bf2c 100644
--- a/third_party/blink/renderer/bindings/BUILD.gn
+++ b/third_party/blink/renderer/bindings/BUILD.gn
@@ -225,6 +225,126 @@
       generated_union_sources_for_testing_in_core
 }
 
+action_with_pydeps("check_generated_file_list") {
+  script = "${bindings_scripts_dir}/check_generated_file_list.py"
+
+  web_idl_database_outputs = get_target_outputs(":web_idl_database")
+  web_idl_database = web_idl_database_outputs[0]
+  result_file = "${bindings_gen_dir}/check_generated_file_list_results.txt"
+
+  inputs = [ web_idl_database ]
+  outputs = [ result_file ]
+
+  file_list = []
+  file_list += [
+    "--kind",
+    "callback_function",
+  ]
+  file_list += generated_callback_function_sources_in_core +
+               generated_callback_function_sources_in_modules
+  file_list += [
+    "--kind",
+    "callback_interface",
+  ]
+  file_list += generated_callback_interface_sources_in_core +
+               generated_callback_interface_sources_in_modules
+  file_list += [
+    "--kind",
+    "dictionary",
+  ]
+  file_list += generated_dictionary_sources_in_core +
+               generated_dictionary_sources_in_modules
+  if (use_blink_extensions_chromeos) {
+    file_list += generated_dictionary_sources_in_extensions_chromeos
+  }
+  file_list += [
+    "--kind",
+    "enumeration",
+  ]
+  file_list += generated_enumeration_sources_in_core +
+               generated_enumeration_sources_in_modules
+  if (use_blink_extensions_chromeos) {
+    file_list += generated_enumeration_sources_in_extensions_chromeos
+  }
+  file_list += [
+    "--kind",
+    "interface",
+  ]
+  file_list += generated_interface_sources_in_core +
+               generated_interface_sources_in_modules -
+               generated_interface_extra_sources_in_modules
+  if (use_blink_extensions_chromeos) {
+    file_list += generated_interface_sources_in_extensions_chromeos
+  }
+  file_list += [
+    "--kind",
+    "namespace",
+  ]
+  file_list += generated_namespace_sources_in_core +
+               generated_namespace_sources_in_modules
+  file_list += [
+    "--kind",
+    "observable_array",
+  ]
+  file_list += generated_observable_array_sources_in_core +
+               generated_observable_array_sources_in_modules
+  file_list += [
+    "--kind",
+    "union",
+  ]
+  file_list +=
+      generated_union_sources_in_core + generated_union_sources_in_modules
+
+  response_file_contents = []
+  foreach(token, file_list) {
+    response_file_contents +=
+        [ string_replace(token, "${root_gen_dir}/", "", 1) ]
+  }
+
+  args = [
+    "--web_idl_database",
+    rebase_path(web_idl_database, root_build_dir),
+    "--root_src_dir",
+    rebase_path("//", root_build_dir),
+    "--root_gen_dir",
+    rebase_path(root_gen_dir, root_build_dir),
+    "--output_reldir",
+    "core=" + rebase_path("${bindings_gen_dir}/core/v8/", root_gen_dir),
+    "--output_reldir",
+    "modules=" + rebase_path("${bindings_gen_dir}/modules/v8/", root_gen_dir),
+  ]
+  if (use_blink_extensions_chromeos) {
+    args += [
+      "--output_reldir",
+      "extensions_chromeos=" +
+          rebase_path("${bindings_gen_dir}/extensions_chromeos/v8/",
+                      root_gen_dir),
+    ]
+  }
+  args += [
+    "--generated_file_list",
+    "{{response_file_name}}",
+    "--output",
+    rebase_path(result_file, root_build_dir),
+  ]
+
+  deps = [
+    # A lot of C++ compile tasks are waiting for the completion of the
+    # bindings generator because most Blink C++ source files directly or
+    # indirectly depend on the generated bindings files.  Since we'd like
+    # `generate_bindings_all` to use the most CPU power and memory so that
+    # it unblocks Blink C++ compile tasks as soon as possible, we do not like
+    # `check_generated_file_list` running in parallel to
+    # `generate_bindings_all`.
+    #
+    # This trick (unnecessary dependency to `generate_bindings_all`) makes
+    # `check_generated_file_list` wait for the completion of
+    # `generate_bindings_all`.
+    ":generate_bindings_all",
+    ":web_idl_database",
+  ]
+}
+
 action_with_pydeps("validate_web_idl") {
   script = "${bindings_scripts_dir}/validate_web_idl.py"
 
diff --git a/third_party/blink/renderer/bindings/generated_in_core.gni b/third_party/blink/renderer/bindings/generated_in_core.gni
index dd3f602..11aacce 100644
--- a/third_party/blink/renderer/bindings/generated_in_core.gni
+++ b/third_party/blink/renderer/bindings/generated_in_core.gni
@@ -7,10 +7,6 @@
 generated_callback_function_sources_in_core = [
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_blob_callback.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_blob_callback.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_close_watcher.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_close_watcher.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_close_watcher_options.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_close_watcher_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_create_html_callback.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_create_html_callback.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_create_script_callback.cc",
@@ -47,8 +43,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_callback.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_intrinsic_sizes_callback.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_intrinsic_sizes_callback.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_ip_address_space.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_ip_address_space.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_layout_callback.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_layout_callback.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_watch_callback.cc",
@@ -61,8 +55,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_no_argument_constructor.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_observer_callback.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_observer_callback.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_observer_callback_options.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_observer_callback_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_reporting_observer_callback.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_reporting_observer_callback.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_resize_observer_callback.cc",
@@ -95,28 +87,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation_event_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation_playback_event_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation_playback_event_init.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigate_event_init.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigate_event_init.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_current_entry_change_event_init.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_current_entry_change_event_init.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_intercept_options.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_intercept_options.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_intercept_or_transition_while_options.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_intercept_or_transition_while_options.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_navigate_options.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_navigate_options.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_options.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_options.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_reload_options.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_reload_options.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_result.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_result.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_transition.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_transition_while_options.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_transition_while_options.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_transition.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_update_current_entry_options.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_update_current_entry_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_assigned_nodes_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_assigned_nodes_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_base_keyframe.cc",
@@ -129,8 +99,12 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_blob_property_bag.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_character_bounds_update_event_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_character_bounds_update_event_init.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_check_visibility_options.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_check_visibility_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_clipboard_event_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_clipboard_event_init.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_close_watcher_options.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_close_watcher_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_composition_event_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_composition_event_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_computed_effect_timing.cc",
@@ -179,6 +153,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_event_listener_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_event_modifier_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_event_modifier_init.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fence_event.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fence_event.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_file_property_bag.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_file_property_bag.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_focus_event_init.cc",
@@ -275,6 +251,26 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mouse_event_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mutation_observer_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mutation_observer_init.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigate_event_init.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigate_event_init.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_current_entry_change_event_init.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_current_entry_change_event_init.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_intercept_options.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_intercept_options.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_intercept_or_transition_while_options.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_intercept_or_transition_while_options.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_navigate_options.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_navigate_options.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_options.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_options.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_reload_options.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_reload_options.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_result.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_result.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_transition_while_options.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_transition_while_options.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_update_current_entry_options.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_update_current_entry_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigator_ua_brand_version.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigator_ua_brand_version.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_optional_effect_timing.cc",
@@ -285,10 +281,14 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_page_transition_event_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_parse_from_string_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_parse_from_string_options.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_pending_beacon_options.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_pending_beacon_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_mark_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_mark_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_measure_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_measure_options.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_observer_callback_options.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_observer_callback_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_observer_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_performance_observer_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_pointer_event_init.cc",
@@ -303,12 +303,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_portal_activate_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_post_message_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_post_message_options.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_structured_serialize_options.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_structured_serialize_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_profiler_frame.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_profiler_frame.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_profiler_marker.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_profiler_marker.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_profiler_init_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_profiler_init_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_profiler_sample.cc",
@@ -333,8 +329,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_writable_pair.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_reporting_observer_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_reporting_observer_options.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_duplex.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_duplex.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_resize_observer_options.cc",
@@ -343,8 +337,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_response_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_into_view_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_into_view_options.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_check_visibility_options.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_check_visibility_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_scroll_state_init.cc",
@@ -361,6 +353,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_static_range_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_stream_pipe_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_stream_pipe_options.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_structured_serialize_options.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_structured_serialize_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_submit_event_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_submit_event_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_text_directive_options.cc",
@@ -410,6 +404,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation_play_state.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_auto_keyword.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_auto_keyword.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_beacon_method.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_beacon_method.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_can_play_type_result.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_can_play_type_result.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_color_space_conversion.cc",
@@ -436,6 +432,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_edit_context_input_panel_policy.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_ending_type.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_ending_type.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fence_reporting_destination.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fence_reporting_destination.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fetch_priority.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fetch_priority.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fill_mode.cc",
@@ -458,12 +456,22 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_orientation.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_pixel_format.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_image_pixel_format.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_ip_address_space.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_ip_address_space.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_interface_interceptor_scope.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_interface_interceptor_scope.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_scope.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_scope.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_native_scroll_behavior.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_native_scroll_behavior.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_focus_reset.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_focus_reset.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_history_behavior.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_history_behavior.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_navigation_type.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_navigation_type.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_scroll_behavior.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_scroll_behavior.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_type.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_type.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_operation_type.cc",
@@ -474,6 +482,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_predefined_color_space.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_premultiply_alpha.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_premultiply_alpha.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_profiler_marker.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_profiler_marker.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_stream_reader_mode.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_stream_reader_mode.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_stream_type.cc",
@@ -492,6 +502,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_credentials.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_destination.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_destination.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_duplex.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_duplex.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_mode.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_mode.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_request_redirect.cc",
@@ -567,8 +579,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_audio_track_list.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_bar_prop.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_bar_prop.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_beacon_method.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_beacon_method.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_before_create_policy_event.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_before_create_policy_event.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_before_unload_event.cc",
@@ -585,6 +595,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_character_data.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_clipboard_event.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_clipboard_event.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_close_watcher.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_close_watcher.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_color_page_popup_controller.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_color_page_popup_controller.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_comment.cc",
@@ -665,8 +677,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_page_rule.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_perspective.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_perspective.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_position_fallback_rule.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_position_fallback_rule.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_position_fallback_rule.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_position_value.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_position_value.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_property_rule.cc",
@@ -709,8 +721,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_transition.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_translate.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_translate.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_try_rule.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_try_rule.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_try_rule.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_unit_value.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_unit_value.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_unparsed_value.cc",
@@ -799,10 +811,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_feature_policy.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fence.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fence.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fence_event.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fence_event.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fence_reporting_destination.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_fence_reporting_destination.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_file.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_file.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_file_list.cc",
@@ -1063,8 +1071,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_handle.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_interface_interceptor.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_interface_interceptor.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_interface_interceptor_scope.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_interface_interceptor_scope.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_interface_request_event.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_interface_request_event.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_mojo_watcher.cc",
@@ -1081,20 +1087,16 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_named_node_map.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigate_event.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigate_event.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_current_entry_change_event.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_current_entry_change_event.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_destination.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_destination.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_focus_reset.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_focus_reset.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_history_entry.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_history_entry.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_navigation_type.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_navigation_type.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_scroll_behavior.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_scroll_behavior.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_transition.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigation_transition.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigator.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigator.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_navigator_ua_data.cc",
@@ -1115,8 +1117,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_page_transition_event.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_pending_beacon.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_pending_beacon.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_pending_beacon_options.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_pending_beacon_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_pending_get_beacon.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_pending_get_beacon.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_pending_post_beacon.cc",
@@ -1704,8 +1704,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_string_stringsequence.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_string_trustedhtml.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_string_trustedhtml.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_trustedhtml_trustedscript_trustedscripturl.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_trustedhtml_trustedscript_trustedscripturl.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_string_trustedscript.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_string_trustedscript.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_string_trustedscripturl.cc",
@@ -1718,6 +1716,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_string_workeroptions.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_stringtreatnullasemptystring_trustedscript.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_stringtreatnullasemptystring_trustedscript.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_trustedhtml_trustedscript_trustedscripturl.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_trustedhtml_trustedscript_trustedscripturl.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_uint32arrayallowshared_unsignedlongsequence.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_uint32arrayallowshared_unsignedlongsequence.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_unsignedlong_unsignedlongsequence.cc",
diff --git a/third_party/blink/renderer/bindings/generated_in_extensions_chromeos.gni b/third_party/blink/renderer/bindings/generated_in_extensions_chromeos.gni
index cbb03a8a..ea6a801 100644
--- a/third_party/blink/renderer/bindings/generated_in_extensions_chromeos.gni
+++ b/third_party/blink/renderer/bindings/generated_in_extensions_chromeos.gni
@@ -12,8 +12,8 @@
 generated_enumeration_sources_in_extensions_chromeos = [
   "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_window_visibility_state.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_window_visibility_state.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_window_state.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_window_state.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_window_state.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/extensions_chromeos/v8/v8_cros_window_state.h",
 ]
 
 generated_interface_sources_in_extensions_chromeos = [
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni
index bb79a60..9a957c0 100644
--- a/third_party/blink/renderer/bindings/generated_in_modules.gni
+++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -45,6 +45,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_position_callback.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_position_error_callback.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_position_error_callback.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_pressure_update_callback.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_pressure_update_callback.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_remote_playback_availability_callback.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_remote_playback_availability_callback.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection_error_callback.cc",
@@ -103,16 +105,12 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ad_properties.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ad_request_config.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ad_request_config.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ad_signals.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ad_signals.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ad_targeting.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ad_targeting.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_address_errors.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_address_errors.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_address_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_address_init.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ads.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ads.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_analyser_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_analyser_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_android_pay_method_data.cc",
@@ -133,6 +131,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_configuration.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_context_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_context_options.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_data_copy_to_options.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_data_copy_to_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_data_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_data_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_decoder_config.cc",
@@ -355,10 +355,10 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gamepad_event_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_get_notification_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_get_notification_options.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_goog_media_constraints_set.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_goog_media_constraints_set.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_goog_media_constraints.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_goog_media_constraints.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_goog_media_constraints_set.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_goog_media_constraints_set.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_bind_group_descriptor.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_bind_group_descriptor.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_bind_group_entry.cc",
@@ -377,8 +377,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_buffer_binding_layout.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_buffer_descriptor.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_buffer_descriptor.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_canvas_alpha_mode.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_canvas_alpha_mode.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_canvas_configuration.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_canvas_configuration.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_color_dict.cc",
@@ -491,16 +489,12 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_handwriting_hints.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_handwriting_hints_query_result.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_handwriting_hints_query_result.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_handwriting_input_type.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_handwriting_input_type.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_handwriting_model_constraint.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_handwriting_model_constraint.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_handwriting_point.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_handwriting_point.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_handwriting_prediction.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_handwriting_prediction.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_handwriting_recognition_type.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_handwriting_recognition_type.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_handwriting_recognizer_query_result.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_handwriting_recognizer_query_result.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_handwriting_segment.cc",
@@ -527,8 +521,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_transaction_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_version_change_event_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_version_change_event_init.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_identity_credential.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_identity_credential.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_identity_credential_logout_r_ps_request.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_identity_credential_logout_r_ps_request.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_identity_credential_request_options.cc",
@@ -549,6 +541,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_image_object.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_image_resource.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_image_resource.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ink_presenter_param.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ink_presenter_param.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ink_trail_style.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ink_trail_style.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_item_details.cc",
@@ -637,36 +631,22 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_permission_descriptor.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_permission_descriptor.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_auto_pad.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_auto_pad.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_context.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_context.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_context_options.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_context_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_clamp_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_clamp_options.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_conv_2d_filter_operand_layout.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_conv_2d_filter_operand_layout.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_context_options.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_context_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_conv_2d_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_conv_2d_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_gemm_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_gemm_options.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_graph_builder.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_graph_builder.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_input_operand_layout.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_input_operand_layout.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_operand_descriptor.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_operand_descriptor.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_operand.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_operand.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_operator.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_operator.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_pool_2d_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_pool_2d_options.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_rounding_type.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_rounding_type.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_tensor.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_tensor.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_tensor_info.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_tensor_info.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_multi_cache_query_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_multi_cache_query_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_native_io_read_result.cc",
@@ -675,6 +655,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_native_io_write_result.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_navigation_preload_state.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_navigation_preload_state.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_make_read_only_options.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_make_read_only_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_message_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_message_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_reading_event_init.cc",
@@ -683,8 +665,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_record_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_scan_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_scan_options.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_make_read_only_options.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_make_read_only_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_write_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_write_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_notification_action.cc",
@@ -777,8 +757,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_pressure_observer_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_pressure_record.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_pressure_record.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_pressure_source.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_pressure_source.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_creation_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_creation_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_descriptor.cc",
@@ -895,8 +873,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_save_file_picker_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_scheduler_post_task_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_scheduler_post_task_options.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_script_wrappable_task_attribution_id.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_script_wrappable_task_attribution_id.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_secure_payment_confirmation_request.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_secure_payment_confirmation_request.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sensor_error_event_init.cc",
@@ -907,10 +883,10 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_share_data.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_shared_storage_run_operation_method_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_shared_storage_run_operation_method_options.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_shared_storage_url_with_metadata.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_shared_storage_url_with_metadata.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_shared_storage_set_method_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_shared_storage_set_method_options.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_shared_storage_url_with_metadata.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_shared_storage_url_with_metadata.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_source_buffer_config.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_source_buffer_config.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_spatial_sensor_options.cc",
@@ -923,8 +899,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_error_event_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_event_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_speech_synthesis_event_init.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_svc_output_metadata.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_svc_output_metadata.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_stereo_panner_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_stereo_panner_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_storage_bucket_options.cc",
@@ -935,6 +909,10 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_storage_event_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_storage_usage_details.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_storage_usage_details.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sub_apps_add_options.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sub_apps_add_options.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_svc_output_metadata.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_svc_output_metadata.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sync_event_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sync_event_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_task_controller_init.cc",
@@ -947,8 +925,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_text_decoder_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_text_encoder_encode_into_result.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_text_encoder_encode_into_result.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_url_pattern_component.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_url_pattern_component.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_url_pattern_component_result.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_url_pattern_component_result.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_url_pattern_init.cc",
@@ -963,8 +939,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_device_filter.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_device_request_options.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_device_request_options.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_color_space.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_color_space.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_color_space_init.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_color_space_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_configuration.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_configuration.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_decoder_config.cc",
@@ -1048,6 +1024,8 @@
 ]
 
 generated_enumeration_sources_in_modules = [
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ad_signals.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ad_signals.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_alpha_option.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_alpha_option.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ancestor_status.cc",
@@ -1062,6 +1040,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_context_state.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_playback_destination.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_playback_destination.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_sample_format.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_sample_format.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_automation_rate.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_automation_rate.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_avc_bitstream_format.cc",
@@ -1154,6 +1134,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_blend_operation.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_buffer_binding_type.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_buffer_binding_type.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_canvas_alpha_mode.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_canvas_alpha_mode.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_compare_function.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_compare_function.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_compilation_message_type.cc",
@@ -1206,6 +1188,10 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_vertex_format.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_vertex_step_mode.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_vertex_step_mode.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_handwriting_input_type.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_handwriting_input_type.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_handwriting_recognition_type.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_handwriting_recognition_type.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hardware_preference.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hardware_preference.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_hdr_metadata_type.cc",
@@ -1264,24 +1250,24 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_port_device_state.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_port_type.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_midi_port_type.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_auto_pad.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_auto_pad.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_conv_2d_filter_operand_layout.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_conv_2d_filter_operand_layout.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_data_type.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_data_type.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_device_preference.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_device_preference.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_model.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_model.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_input_operand_layout.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_input_operand_layout.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_model_format.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_model_format.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_model_loader.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_model_loader.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_operand_type.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_operand_type.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_power_preference.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_power_preference.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_tensor.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_tensor.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_tensor_info.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_tensor_info.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_rounding_type.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_rounding_type.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_notification_action_type.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_notification_action_type.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_notification_direction.cc",
@@ -1316,6 +1302,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_connection_close_reason.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_connection_state.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_connection_state.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_pressure_source.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_pressure_source.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_type.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_type.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_encryption_key_name.cc",
@@ -1386,12 +1374,16 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_storage_bucket_durability.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sub_apps_service_add_result_code.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sub_apps_service_add_result_code.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_system_audio_preference_enum.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_system_audio_preference_enum.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_task_priority.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_task_priority.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_track_default_type.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_track_default_type.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_transfer_function.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_transfer_function.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_url_pattern_component.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_url_pattern_component.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_direction.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_direction.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_endpoint_type.cc",
@@ -1406,8 +1398,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_user_idle_state.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_color_primaries.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_color_primaries.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_color_space_init.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_color_space_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_matrix_coefficients.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_matrix_coefficients.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_pixel_format.cc",
@@ -1469,6 +1459,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_absolute_orientation_sensor.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_accelerometer.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_accelerometer.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ads.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ads.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ambient_light_sensor.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ambient_light_sensor.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_analyser_node.cc",
@@ -1485,8 +1477,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_context.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_data.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_data.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_data_copy_to_options.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_data_copy_to_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_decoder.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_decoder.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_destination_node.cc",
@@ -1503,8 +1493,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_param_map.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_processing_event.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_processing_event.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_sample_format.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_sample_format.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_scheduled_source_node.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_scheduled_source_node.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_audio_track.cc",
@@ -1637,8 +1625,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_crypto.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_crypto_key.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_crypto_key.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_css.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_css.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_data_transfer_item.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_data_transfer_item.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_database.cc",
@@ -1789,10 +1775,10 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_geolocation_position_error.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_adapter_info.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_adapter_info.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_adapter.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_adapter.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_adapter_info.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_adapter_info.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_bind_group.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_bind_group.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_bind_group_layout.cc",
@@ -1905,6 +1891,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_transaction.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_version_change_event.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idb_version_change_event.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_identity_credential.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_identity_credential.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idle_detector.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_idle_detector.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_iir_filter_node.cc",
@@ -1921,8 +1909,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_image_track_list.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ink.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ink.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ink_presenter_param.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ink_presenter_param.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_input_device_info.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_input_device_info.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_install_event.cc",
@@ -2019,6 +2005,22 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_mime_type.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_mime_type_array.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_mime_type_array.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_context.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_context.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_graph_builder.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_graph_builder.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_model.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_model.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_model_loader.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_model_loader.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_operand.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_operand.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_operator.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_operator.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_mojo.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_mojo.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_native_io_file.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_native_io_file.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_native_io_file_manager.cc",
@@ -2029,8 +2031,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_navigation_preload_manager.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_navigator.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_navigator.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_mojo.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_mojo.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_navigator_managed_data.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_navigator_managed_data.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ndef_message.cc",
@@ -2147,8 +2147,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presentation_request.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_pressure_observer.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_pressure_observer.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_pressure_update_callback.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_pressure_update_callback.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_event.cc",
@@ -2223,12 +2221,14 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_screen.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_screen_detailed.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_screen_detailed.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_screen_orientation.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_screen_orientation.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_screen_details.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_screen_details.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_screen_orientation.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_screen_orientation.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_script_processor_node.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_script_processor_node.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_script_wrappable_task_attribution_id.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_script_wrappable_task_attribution_id.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sensor.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sensor.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sensor_error_event.cc",
@@ -2301,8 +2301,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_storage_manager.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sub_apps.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sub_apps.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sub_apps_add_options.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sub_apps_add_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_subtle_crypto.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_subtle_crypto.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_svg_element.cc",
@@ -2311,8 +2309,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sync_event.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sync_manager.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_sync_manager.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_system_audio_preference_enum.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_system_audio_preference_enum.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_task_controller.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_task_controller.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_task_priority_change_event.cc",
@@ -2365,6 +2361,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_isochronous_out_transfer_result.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_out_transfer_result.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_usb_out_transfer_result.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_color_space.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_color_space.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_decoder.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_decoder.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_encoder.cc",
@@ -2570,6 +2568,8 @@
 ]
 
 generated_namespace_sources_in_modules = [
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_css.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_css.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_buffer_usage.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_buffer_usage.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_gpu_color_write.cc",
@@ -2611,8 +2611,6 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_boolean_mediatrackconstraints.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_canvasfilter_string.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_canvasfilter_string.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_htmlvideoelement_videoframe.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_htmlvideoelement_videoframe.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_canvasrenderingcontext2d_gpucanvascontext_imagebitmaprenderingcontext_webgl2renderingcontext_webglrenderingcontext.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_canvasrenderingcontext2d_gpucanvascontext_imagebitmaprenderingcontext_webgl2renderingcontext_webglrenderingcontext.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_client_messageport_serviceworker.cc",
@@ -2659,6 +2657,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_gpuorigin3ddict_unsignedlongenforcerangesequence.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_htmlformelement_passwordcredentialdata.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_htmlformelement_passwordcredentialdata.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_htmlvideoelement_videoframe.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_htmlvideoelement_videoframe.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_idbcursor_idbindex_idbobjectstore.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_idbcursor_idbindex_idbobjectstore.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_union_idbindex_idbobjectstore.cc",
@@ -2695,12 +2695,12 @@
     "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_tcp_socket_open_info.h",
     "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_tcp_socket_options.cc",
     "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_tcp_socket_options.h",
+    "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_udp_message.cc",
+    "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_udp_message.h",
     "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_udp_socket_open_info.cc",
     "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_udp_socket_open_info.h",
     "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_udp_socket_options.cc",
     "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_udp_socket_options.h",
-    "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_udp_message.h",
-    "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_udp_message.cc",
   ]
   generated_interface_sources_in_modules += [
     "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_tcp_socket.cc",
@@ -2756,8 +2756,7 @@
     "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_window_controls_overlay_geometry_change_event_init.cc",
     "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_window_controls_overlay_geometry_change_event_init.h",
   ]
-
-  generated_enumeration_sources_in_modules += [
+  generated_interface_sources_in_modules += [
     "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_window_controls_overlay.cc",
     "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_window_controls_overlay.h",
     "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_window_controls_overlay_geometry_change_event.cc",
@@ -2765,12 +2764,14 @@
   ]
 }
 
-generated_interface_sources_in_modules += [
+generated_interface_extra_sources_in_modules = [
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/init_idl_interfaces.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/init_idl_interfaces.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/properties_per_feature_installer.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/properties_per_feature_installer.h",
 ]
+generated_interface_sources_in_modules +=
+    generated_interface_extra_sources_in_modules
 
 # Generated sources for testing
 
@@ -2779,9 +2780,12 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_internals.h",
 ]
 
-generated_interface_sources_for_testing_in_modules += [
+generated_interface_extra_sources_for_testing_in_modules = [
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/init_idl_interfaces_for_testing.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/init_idl_interfaces_for_testing.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/properties_per_feature_installer_for_testing.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/properties_per_feature_installer_for_testing.h",
 ]
+
+generated_interface_sources_for_testing_in_modules +=
+    generated_interface_extra_sources_for_testing_in_modules
diff --git a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc
index 3469fab..b0504106 100644
--- a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc
+++ b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc
@@ -633,8 +633,7 @@
   WriteOneByte(track->enabled());
   WriteOneByte(track->muted());
   WriteUint32Enum(SerializeContentHint(track->Component()->ContentHint()));
-  WriteUint32Enum(
-      SerializeReadyState(track->Component()->Source()->GetReadyState()));
+  WriteUint32Enum(SerializeReadyState(track->Component()->GetReadyState()));
   return true;
 }
 
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/path_manager.py b/third_party/blink/renderer/bindings/scripts/bind_gen/path_manager.py
index feab07d2..a726b475 100644
--- a/third_party/blink/renderer/bindings/scripts/bind_gen/path_manager.py
+++ b/third_party/blink/renderer/bindings/scripts/bind_gen/path_manager.py
@@ -110,17 +110,19 @@
         elif len(components) == 2:
             assert components[0] == "core"
             assert components[1] == "modules"
-            self._is_cross_components = True
             # ObservableArray and union types do not support cross-component
             # code generation because clients of IDL observable array and IDL
             # union types must be on an upper or same layer to any of element
             # type and union members.
             if isinstance(idl_definition,
                           (web_idl.ObservableArray, web_idl.Union)):
+                self._is_cross_components = False
                 self._api_component = components[1]
+                self._impl_component = components[1]
             else:
+                self._is_cross_components = True
                 self._api_component = components[0]
-            self._impl_component = components[1]
+                self._impl_component = components[1]
         else:
             assert False
 
diff --git a/third_party/blink/renderer/bindings/scripts/check_generated_file_list.py b/third_party/blink/renderer/bindings/scripts/check_generated_file_list.py
new file mode 100644
index 0000000..321a92e
--- /dev/null
+++ b/third_party/blink/renderer/bindings/scripts/check_generated_file_list.py
@@ -0,0 +1,176 @@
+# Copyright 2022 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""
+Checks the file list of generated bindings defined in generated_in_*.gni
+if there is no missing entry.
+"""
+
+import argparse
+import itertools
+import sys
+
+import bind_gen
+import web_idl
+
+from bind_gen.path_manager import PathManager
+
+
+def parse_output_reldirs(reldirs):
+    required = ["core", "modules"]
+    valid = required + ["extensions_chromeos"]
+    result = {}
+    for key_value_pair in reldirs:
+        key, value = key_value_pair.split("=", 1)
+        key = key.strip()
+        result[key] = value
+
+    for c in required:
+        assert c in result, "missing required --output_reldir \"{0}\"".format(
+            c)
+
+    for c in result.keys():
+        assert c in valid, "invalid --output_reldir \"{0}\"".format(c)
+
+    return result
+
+
+def parse_options():
+    parser = argparse.ArgumentParser(
+        description="Check the generated file list of Blink bindings")
+    parser.add_argument("--web_idl_database",
+                        required=True,
+                        type=str,
+                        help="filepath of the input database")
+    parser.add_argument("--root_src_dir",
+                        required=True,
+                        type=str,
+                        help="root directory of chromium project, i.e. \"//\"")
+    parser.add_argument("--root_gen_dir",
+                        required=True,
+                        type=str,
+                        help="root directory of generated code files, i.e. "
+                        "\"//out/Default/gen\"")
+    parser.add_argument(
+        "--output_reldir",
+        metavar="KEY=VALUE",
+        action="append",
+        help="output directory of KEY component relative to root_gen_dir.")
+    parser.add_argument("--generated_file_list",
+                        required=True,
+                        type=str,
+                        help="filepath of the generated file list")
+    parser.add_argument("--output",
+                        required=True,
+                        type=str,
+                        help="filepath of the check results")
+
+    options = parser.parse_args()
+
+    return options
+
+
+def main():
+    options = parse_options()
+
+    output_reldirs = parse_output_reldirs(options.output_reldir)
+    component_reldirs = {}
+    for component, reldir in output_reldirs.items():
+        component_reldirs[web_idl.Component(component)] = reldir
+
+    bind_gen.init(web_idl_database_path=options.web_idl_database,
+                  root_src_dir=options.root_src_dir,
+                  root_gen_dir=options.root_gen_dir,
+                  component_reldirs=component_reldirs,
+                  enable_style_format=False)
+    web_idl_database = bind_gen.package_initializer.package_initializer(
+    ).web_idl_database()
+    idl_definitions = {
+        "callback_function": web_idl_database.callback_functions,
+        "callback_interface": web_idl_database.callback_interfaces,
+        "dictionary": web_idl_database.dictionaries,
+        "enumeration": web_idl_database.enumerations,
+        "interface": web_idl_database.interfaces,
+        "namespace": web_idl_database.namespaces,
+        "observable_array": web_idl_database.observable_arrays,
+        "union": web_idl_database.union_types,
+    }
+
+    error_log = []
+
+    # Read generated_file_list into `filepaths`.
+    filepaths = {}  # {kind: set(filepaths...)}
+    kind = None
+    with open(options.generated_file_list) as input:
+        for token in itertools.chain.from_iterable(line.split()
+                                                   for line in input):
+            if token == "--kind":
+                kind = None
+                continue
+            if kind is None:
+                kind = token
+                filepaths.setdefault(kind, set())
+                continue
+            filepaths[kind].add(token)
+
+    def check_if_listed(file_set, path, component, kind):
+        try:
+            file_set.remove(path)
+        except KeyError:
+            error_log.append(
+                "\"{path}\" is generated but not listed in the file list of "
+                "\"{kind}\" in generated_in_{component}.gni.\n".format(
+                    path=path, component=component, kind=kind))
+
+    # Check whether all generated files are listed appropriately.
+    for kind, file_set in filepaths.items():
+        for idl_definition in idl_definitions[kind]:
+            # No check about testing files for now. It's quite rare for Blink
+            # developers to add testing *.idl, so there must be almost no
+            # chance for them to break the generated file lists.
+            if idl_definition.code_generator_info.for_testing:
+                continue
+
+            if kind == "callback_function" and idl_definition.identifier in (
+                    "OnErrorEventHandlerNonNull",
+                    "OnBeforeUnloadEventHandlerNonNull"):
+                # OnErrorEventHandlerNonNull and
+                # OnBeforeUnloadEventHandlerNonNull are unified into
+                # EventHandlerNonNull, and they won't be used.
+                continue
+
+            path_manager = PathManager(idl_definition)
+            check_if_listed(file_set, path_manager.api_path(ext="cc"),
+                            path_manager.api_component, kind)
+            check_if_listed(file_set, path_manager.api_path(ext="h"),
+                            path_manager.api_component, kind)
+            if path_manager.is_cross_components:
+                check_if_listed(file_set, path_manager.impl_path(ext="cc"),
+                                path_manager.impl_component, kind)
+                check_if_listed(file_set, path_manager.impl_path(ext="h"),
+                                path_manager.impl_component, kind)
+        for path in file_set:
+            error_log.append(
+                "\"{path}\" is listed in the file list of \"{kind}\", but "
+                "the file is not generated as {kind}.\n".format(path=path,
+                                                                kind=kind))
+
+    with open(options.output, mode="w") as output:
+        for message in error_log:
+            output.write(message)
+
+    if error_log:
+        sys.stderr.write(
+            "Error: {} errors were detected in file listing of the generated "
+            "Blink-V8 bindings files.\n\n".format(len(error_log)))
+        for message in error_log:
+            sys.stderr.write(message)
+        sys.stderr.write("\n")
+        sys.exit(1)
+
+    if sys.stdout.isatty():
+        sys.stdout.write("No error was detected.\n")
+
+
+if __name__ == "__main__":
+    main()
diff --git a/third_party/blink/renderer/bindings/scripts/check_generated_file_list.pydeps b/third_party/blink/renderer/bindings/scripts/check_generated_file_list.pydeps
new file mode 100644
index 0000000..71a741a
--- /dev/null
+++ b/third_party/blink/renderer/bindings/scripts/check_generated_file_list.pydeps
@@ -0,0 +1,86 @@
+# Generated by running:
+#   build/print_python_deps.py --root third_party/blink/renderer/bindings/scripts --output third_party/blink/renderer/bindings/scripts/check_generated_file_list.pydeps third_party/blink/renderer/bindings/scripts/check_generated_file_list.py
+../../../../mako/mako/mako/__init__.py
+../../../../mako/mako/mako/_ast_util.py
+../../../../mako/mako/mako/ast.py
+../../../../mako/mako/mako/cache.py
+../../../../mako/mako/mako/codegen.py
+../../../../mako/mako/mako/compat.py
+../../../../mako/mako/mako/exceptions.py
+../../../../mako/mako/mako/ext/__init__.py
+../../../../mako/mako/mako/filters.py
+../../../../mako/mako/mako/lexer.py
+../../../../mako/mako/mako/parsetree.py
+../../../../mako/mako/mako/pygen.py
+../../../../mako/mako/mako/pyparser.py
+../../../../mako/mako/mako/runtime.py
+../../../../mako/mako/mako/template.py
+../../../../mako/mako/mako/util.py
+../../../../markupsafe/__init__.py
+../../../../markupsafe/_compat.py
+../../../../markupsafe/_native.py
+../../../../pyjson5/src/json5/__init__.py
+../../../../pyjson5/src/json5/lib.py
+../../../../pyjson5/src/json5/parser.py
+../../../../pyjson5/src/json5/version.py
+../../build/scripts/blinkbuild/__init__.py
+../../build/scripts/blinkbuild/name_style_converter.py
+bind_gen/__init__.py
+bind_gen/blink_v8_bridge.py
+bind_gen/callback_function.py
+bind_gen/callback_interface.py
+bind_gen/code_node.py
+bind_gen/code_node_cxx.py
+bind_gen/codegen_accumulator.py
+bind_gen/codegen_context.py
+bind_gen/codegen_expr.py
+bind_gen/codegen_format.py
+bind_gen/codegen_utils.py
+bind_gen/dictionary.py
+bind_gen/enumeration.py
+bind_gen/interface.py
+bind_gen/mako_renderer.py
+bind_gen/name_style.py
+bind_gen/namespace.py
+bind_gen/observable_array.py
+bind_gen/package_initializer.py
+bind_gen/path_manager.py
+bind_gen/style_format.py
+bind_gen/task_queue.py
+bind_gen/typedef.py
+bind_gen/union.py
+check_generated_file_list.py
+web_idl/__init__.py
+web_idl/argument.py
+web_idl/ast_group.py
+web_idl/attribute.py
+web_idl/callback_function.py
+web_idl/callback_interface.py
+web_idl/code_generator_info.py
+web_idl/composition_parts.py
+web_idl/constant.py
+web_idl/constructor.py
+web_idl/database.py
+web_idl/database_builder.py
+web_idl/dictionary.py
+web_idl/enumeration.py
+web_idl/exposure.py
+web_idl/extended_attribute.py
+web_idl/file_io.py
+web_idl/function_like.py
+web_idl/idl_compiler.py
+web_idl/idl_type.py
+web_idl/includes.py
+web_idl/interface.py
+web_idl/ir_builder.py
+web_idl/ir_map.py
+web_idl/literal_constant.py
+web_idl/make_copy.py
+web_idl/namespace.py
+web_idl/observable_array.py
+web_idl/operation.py
+web_idl/reference.py
+web_idl/runtime_enabled_features.py
+web_idl/typedef.py
+web_idl/union.py
+web_idl/user_defined_type.py
diff --git a/third_party/blink/renderer/core/css/container_query_evaluator_test.cc b/third_party/blink/renderer/core/css/container_query_evaluator_test.cc
index c4031871..f661c8de 100644
--- a/third_party/blink/renderer/core/css/container_query_evaluator_test.cc
+++ b/third_party/blink/renderer/core/css/container_query_evaluator_test.cc
@@ -614,17 +614,10 @@
   EXPECT_TRUE(Eval("style(--my-prop:)", "--my-prop", ""));
   EXPECT_TRUE(Eval("style(--my-prop: )", "--my-prop", ""));
 
-  EXPECT_FALSE(Eval("style(--my-prop)", "--my-prop", " "));
-  EXPECT_FALSE(Eval("style(--my-prop:)", "--my-prop", " "));
-  EXPECT_FALSE(Eval("style(--my-prop: )", "--my-prop", " "));
-
   EXPECT_TRUE(Eval("style(--my-prop:10px)", "--my-prop", "10px"));
   EXPECT_TRUE(Eval("style(--my-prop: 10px)", "--my-prop", "10px"));
-  EXPECT_FALSE(Eval("style(--my-prop:10px )", "--my-prop", "10px"));
-  EXPECT_FALSE(Eval("style(--my-prop:10px)", "--my-prop", "10px "));
-  EXPECT_FALSE(Eval("style(--my-prop: 10px)", "--my-prop", "10px "));
-  EXPECT_TRUE(Eval("style(--my-prop:10px )", "--my-prop", "10px "));
-  EXPECT_TRUE(Eval("style(--my-prop: 10px )", "--my-prop", "10px "));
+  EXPECT_TRUE(Eval("style(--my-prop:10px )", "--my-prop", "10px"));
+  EXPECT_TRUE(Eval("style(--my-prop: 10px )", "--my-prop", "10px"));
 }
 
 TEST_F(ContainerQueryEvaluatorTest, FindContainer) {
diff --git a/third_party/blink/renderer/core/css/media_query_evaluator.cc b/third_party/blink/renderer/core/css/media_query_evaluator.cc
index 687e6a6f..7c7c9688 100644
--- a/third_party/blink/renderer/core/css/media_query_evaluator.cc
+++ b/third_party/blink/renderer/core/css/media_query_evaluator.cc
@@ -1357,6 +1357,51 @@
   return result ? KleeneValue::kTrue : KleeneValue::kFalse;
 }
 
+namespace {
+
+void ConsumeWhitespace(Vector<CSSParserToken>::const_iterator& iterator,
+                       const Vector<CSSParserToken>::const_iterator& end) {
+  while (iterator != end && (*iterator).GetType() == kWhitespaceToken) {
+    iterator++;
+  }
+}
+
+void ConsumeWhitespaceReverse(
+    Vector<CSSParserToken>::const_iterator& iterator,
+    const Vector<CSSParserToken>::const_iterator& start) {
+  while (iterator != start && (*(iterator - 1)).GetType() == kWhitespaceToken) {
+    iterator--;
+  }
+}
+
+bool TokensEqualIgnoringLeadingAndTrailingSpaces(
+    const CSSVariableData* value1,
+    const CSSVariableData* value2) {
+  if (value1 == value2) {
+    return true;
+  }
+  if (!value1 || !value2) {
+    return false;
+  }
+
+  const Vector<CSSParserToken>& tokens1 = value1->Tokens();
+  const Vector<CSSParserToken>& tokens2 = value2->Tokens();
+
+  Vector<CSSParserToken>::const_iterator tokens1_start = tokens1.begin();
+  Vector<CSSParserToken>::const_iterator tokens1_end = tokens1.end();
+  Vector<CSSParserToken>::const_iterator tokens2_start = tokens2.begin();
+  Vector<CSSParserToken>::const_iterator tokens2_end = tokens2.end();
+
+  ConsumeWhitespace(tokens1_start, tokens1_end);
+  ConsumeWhitespaceReverse(tokens1_end, tokens1_start);
+  ConsumeWhitespace(tokens2_start, tokens2_end);
+  ConsumeWhitespaceReverse(tokens2_end, tokens2_start);
+
+  return std::equal(tokens1_start, tokens1_end, tokens2_start, tokens2_end);
+}
+
+}  // namespace
+
 KleeneValue MediaQueryEvaluator::EvalStyleFeature(
     const MediaQueryFeatureExpNode& feature,
     MediaQueryResultFlags* result_flags) const {
@@ -1375,13 +1420,20 @@
   DCHECK(bounds.right.value.IsCSSValue());
   DCHECK(media_values_->GetComputedStyle());
 
-  return base::ValuesEquivalent(
-             media_values_->GetComputedStyle()->GetVariableData(
-                 AtomicString(feature.Name())),
-             To<CSSCustomPropertyDeclaration>(bounds.right.value.GetCSSValue())
-                 .Value())
-             ? KleeneValue::kTrue
-             : KleeneValue::kFalse;
+  CSSVariableData* computed =
+      media_values_->GetComputedStyle()->GetVariableData(
+          AtomicString(feature.Name()));
+  CSSVariableData* queried =
+      To<CSSCustomPropertyDeclaration>(bounds.right.value.GetCSSValue())
+          .Value();
+
+  // TODO(crbug.com/1220144): Compare the two CSSVariableData using
+  // base::ValuesEquivalent when we correctly strip leading and trailing
+  // whitespaces for custom property values.
+  if (TokensEqualIgnoringLeadingAndTrailingSpaces(computed, queried)) {
+    return KleeneValue::kTrue;
+  }
+  return KleeneValue::kFalse;
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/paint/replaced_painter.cc b/third_party/blink/renderer/core/paint/replaced_painter.cc
index c5875a5d..a8ebe06 100644
--- a/third_party/blink/renderer/core/paint/replaced_painter.cc
+++ b/third_party/blink/renderer/core/paint/replaced_painter.cc
@@ -9,6 +9,7 @@
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/web_feature.h"
 #include "third_party/blink/renderer/core/layout/layout_replaced.h"
+#include "third_party/blink/renderer/core/layout/layout_view.h"
 #include "third_party/blink/renderer/core/layout/svg/layout_svg_root.h"
 #include "third_party/blink/renderer/core/mobile_metrics/mobile_friendliness_checker.h"
 #include "third_party/blink/renderer/core/paint/box_painter.h"
@@ -200,9 +201,19 @@
       auto content_area = content_size.Width() * content_size.Height();
 
       DCHECK_GT(overflow_area, content_area);
+      const float device_pixel_ratio =
+          layout_replaced_.GetDocument().DevicePixelRatio();
+      const int overflow_outside_content_rect =
+          (overflow_area - content_area).ToInt() / pow(device_pixel_ratio, 2);
       UMA_HISTOGRAM_COUNTS_100000(
           "Blink.Overflow.ReplacedElementAreaOutsideContentRect",
-          (overflow_area - content_area).ToInt());
+          overflow_outside_content_rect);
+
+      constexpr int kMaxContentBreakageHeuristic = 5000;
+      if (overflow_outside_content_rect > kMaxContentBreakageHeuristic) {
+        UseCounter::Count(layout_replaced_.GetDocument(),
+                          WebFeature::kReplacedElementPaintedWithLargeOverflow);
+      }
     }
   }
 
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_track_generator.cc b/third_party/blink/renderer/modules/breakout_box/media_stream_track_generator.cc
index d1256ba..33bc7c3 100644
--- a/third_party/blink/renderer/modules/breakout_box/media_stream_track_generator.cc
+++ b/third_party/blink/renderer/modules/breakout_box/media_stream_track_generator.cc
@@ -143,7 +143,7 @@
 
 PushableMediaStreamVideoSource* MediaStreamTrackGenerator::PushableVideoSource()
     const {
-  DCHECK_EQ(Component()->Source()->GetType(), MediaStreamSource::kTypeVideo);
+  DCHECK_EQ(Component()->GetSourceType(), MediaStreamSource::kTypeVideo);
   return static_cast<PushableMediaStreamVideoSource*>(
       GetExecutionContext()->GetTaskRunner(TaskType::kInternalMediaRealTime),
       MediaStreamVideoSource::GetVideoSource(Component()->Source()));
diff --git a/third_party/blink/renderer/modules/breakout_box/media_stream_track_processor.cc b/third_party/blink/renderer/modules/breakout_box/media_stream_track_processor.cc
index 2e52c83..194d497 100644
--- a/third_party/blink/renderer/modules/breakout_box/media_stream_track_processor.cc
+++ b/third_party/blink/renderer/modules/breakout_box/media_stream_track_processor.cc
@@ -60,7 +60,7 @@
   if (source_stream_)
     return source_stream_;
 
-  if (input_track_->Component()->Source()->GetType() ==
+  if (input_track_->Component()->GetSourceType() ==
       MediaStreamSource::kTypeVideo) {
     CreateVideoSourceStream(script_state);
   } else {
diff --git a/third_party/blink/renderer/modules/file_system_access/file_system_read_write_options.idl b/third_party/blink/renderer/modules/file_system_access/file_system_read_write_options.idl
index 3af55da..6fb3cc8d 100644
--- a/third_party/blink/renderer/modules/file_system_access/file_system_read_write_options.idl
+++ b/third_party/blink/renderer/modules/file_system_access/file_system_read_write_options.idl
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// TODO(fivedots): Replace link with explainer, once it lands.
-// https://docs.google.com/document/d/1g7ZCqZ5NdiU7oqyCpsc2iZ7rRAY1ZXO-9VoG4LfP7fM
+// TODO(fivedots): Replace link with one pointing to spec, once it lands.
+// https://github.com/whatwg/fs/blob/main/AccessHandle.md
 
 dictionary FileSystemReadWriteOptions {
-  [EnforceRange] unsigned long long at;
+  [EnforceRange] unsigned long long at = 0;
 };
diff --git a/third_party/blink/renderer/modules/file_system_access/file_system_sync_access_handle.idl b/third_party/blink/renderer/modules/file_system_access/file_system_sync_access_handle.idl
index 7956c00..a3afbb0 100644
--- a/third_party/blink/renderer/modules/file_system_access/file_system_sync_access_handle.idl
+++ b/third_party/blink/renderer/modules/file_system_access/file_system_sync_access_handle.idl
@@ -27,9 +27,9 @@
 [
   RaisesException, Measure
 ] unsigned long long read([AllowShared] ArrayBufferView buffer,
-                           FileSystemReadWriteOptions options);
+                           optional FileSystemReadWriteOptions options = {});
 [
   RaisesException, Measure
 ] unsigned long long write([AllowShared] ArrayBufferView buffer,
-                           FileSystemReadWriteOptions options);
+                           optional FileSystemReadWriteOptions options = {});
 };
diff --git a/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.cc b/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.cc
index abcae2c..26d8582 100644
--- a/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.cc
+++ b/third_party/blink/renderer/modules/imagecapture/image_capture_frame_grabber.cc
@@ -300,7 +300,7 @@
   DCHECK(!!callbacks);
 
   DCHECK(component && component->GetPlatformTrack());
-  DCHECK_EQ(MediaStreamSource::kTypeVideo, component->Source()->GetType());
+  DCHECK_EQ(MediaStreamSource::kTypeVideo, component->GetSourceType());
 
   if (frame_grab_in_progress_) {
     // Reject grabFrame()s too close back to back.
diff --git a/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.cc b/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.cc
index 56dbcc9..a2475b8d 100644
--- a/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.cc
+++ b/third_party/blink/renderer/modules/mediarecorder/audio_track_recorder.cc
@@ -66,7 +66,7 @@
       encoder_task_runner_(encoder_thread_->GetTaskRunner()) {
   DCHECK(IsMainThread());
   DCHECK(track_);
-  DCHECK(track_->Source()->GetType() == MediaStreamSource::kTypeAudio);
+  DCHECK(track_->GetSourceType() == MediaStreamSource::kTypeAudio);
 
   // Connect the source provider to the track as a sink.
   ConnectToTrack();
diff --git a/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc b/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc
index 8a99d3de..59c3cc1 100644
--- a/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc
+++ b/third_party/blink/renderer/modules/mediarecorder/media_recorder_handler.cc
@@ -275,12 +275,11 @@
   }
 
   const bool use_video_tracks =
-      !video_tracks_.IsEmpty() && video_tracks_[0]->Source()->GetReadyState() !=
-                                      MediaStreamSource::kReadyStateEnded;
-  const bool use_audio_tracks = !audio_tracks_.IsEmpty() &&
-                                audio_tracks_[0]->GetPlatformTrack() &&
-                                audio_tracks_[0]->Source()->GetReadyState() !=
-                                    MediaStreamSource::kReadyStateEnded;
+      !video_tracks_.IsEmpty() &&
+      video_tracks_[0]->GetReadyState() != MediaStreamSource::kReadyStateEnded;
+  const bool use_audio_tracks =
+      !audio_tracks_.IsEmpty() && audio_tracks_[0]->GetPlatformTrack() &&
+      audio_tracks_[0]->GetReadyState() != MediaStreamSource::kReadyStateEnded;
 
   if (!use_video_tracks && !use_audio_tracks) {
     LOG(WARNING) << __func__ << ": no tracks to be recorded.";
@@ -676,7 +675,7 @@
     const MediaStreamComponent& track,
     bool is_video) {
   const bool track_live_and_enabled =
-      track.Source()->GetReadyState() == MediaStreamSource::kReadyStateLive &&
+      track.GetReadyState() == MediaStreamSource::kReadyStateLive &&
       track.Enabled();
   if (webm_muxer_)
     webm_muxer_->SetLiveAndEnabled(track_live_and_enabled, is_video);
@@ -685,12 +684,12 @@
 void MediaRecorderHandler::OnSourceReadyStateChanged() {
   for (const auto& track : video_tracks_) {
     DCHECK(track->Source());
-    if (track->Source()->GetReadyState() != MediaStreamSource::kReadyStateEnded)
+    if (track->GetReadyState() != MediaStreamSource::kReadyStateEnded)
       return;
   }
   for (const auto& track : audio_tracks_) {
     DCHECK(track->Source());
-    if (track->Source()->GetReadyState() != MediaStreamSource::kReadyStateEnded)
+    if (track->GetReadyState() != MediaStreamSource::kReadyStateEnded)
       return;
   }
   // All tracks are ended, so stop the recorder in accordance with
diff --git a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
index 5bed60c..62c33df 100644
--- a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
+++ b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
@@ -622,7 +622,7 @@
       main_task_runner_(std::move(main_task_runner)) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(main_sequence_checker_);
   DCHECK(track_);
-  DCHECK(track_->Source()->GetType() == MediaStreamSource::kTypeVideo);
+  DCHECK(track_->GetSourceType() == MediaStreamSource::kTypeVideo);
 
   initialize_encoder_cb_ = WTF::BindRepeating(
       &VideoTrackRecorderImpl::InitializeEncoder, weak_factory_.GetWeakPtr(),
diff --git a/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc b/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc
index 3a2a6928..484b4c84 100644
--- a/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc
+++ b/third_party/blink/renderer/modules/mediastream/apply_constraints_processor.cc
@@ -63,11 +63,11 @@
   }
   request_completed_cb_ = std::move(callback);
   current_request_ = request;
-  if (current_request_->Track()->Source()->GetType() ==
+  if (current_request_->Track()->GetSourceType() ==
       MediaStreamSource::kTypeVideo) {
     ProcessVideoRequest();
   } else {
-    DCHECK_EQ(current_request_->Track()->Source()->GetType(),
+    DCHECK_EQ(current_request_->Track()->GetSourceType(),
               MediaStreamSource::kTypeAudio);
     ProcessAudioRequest();
   }
@@ -76,7 +76,7 @@
 void ApplyConstraintsProcessor::ProcessAudioRequest() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(current_request_);
-  DCHECK_EQ(current_request_->Track()->Source()->GetType(),
+  DCHECK_EQ(current_request_->Track()->GetSourceType(),
             MediaStreamSource::kTypeAudio);
   DCHECK(request_completed_cb_);
   blink::MediaStreamAudioSource* audio_source = GetCurrentAudioSource();
@@ -97,7 +97,7 @@
 void ApplyConstraintsProcessor::ProcessVideoRequest() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(current_request_);
-  DCHECK_EQ(current_request_->Track()->Source()->GetType(),
+  DCHECK_EQ(current_request_->Track()->GetSourceType(),
             MediaStreamSource::kTypeVideo);
   DCHECK(request_completed_cb_);
   video_source_ = GetCurrentVideoSource();
@@ -266,7 +266,7 @@
     Vector<media::VideoCaptureFormat> formats) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(current_request_);
-  DCHECK_EQ(current_request_->Track()->Source()->GetType(),
+  DCHECK_EQ(current_request_->Track()->GetSourceType(),
             MediaStreamSource::kTypeVideo);
   DCHECK(request_completed_cb_);
   DCHECK_GT(formats.size(), 0U);
@@ -329,7 +329,7 @@
 bool ApplyConstraintsProcessor::AbortIfVideoRequestStateInvalid() {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK(current_request_);
-  DCHECK_EQ(current_request_->Track()->Source()->GetType(),
+  DCHECK_EQ(current_request_->Track()->GetSourceType(),
             MediaStreamSource::kTypeVideo);
   DCHECK(request_completed_cb_);
 
diff --git a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc
index 657d7ca..faf76ae 100644
--- a/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc
+++ b/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.cc
@@ -135,7 +135,7 @@
     bool is_clone)
     : BrowserCaptureMediaStreamTrack(execution_context,
                                      component,
-                                     component->Source()->GetReadyState(),
+                                     component->GetReadyState(),
                                      std::move(callback),
                                      descriptor_id,
                                      is_clone) {}
diff --git a/third_party/blink/renderer/modules/mediastream/focusable_media_stream_track.cc b/third_party/blink/renderer/modules/mediastream/focusable_media_stream_track.cc
index 6c479b15..ffffdb9 100644
--- a/third_party/blink/renderer/modules/mediastream/focusable_media_stream_track.cc
+++ b/third_party/blink/renderer/modules/mediastream/focusable_media_stream_track.cc
@@ -20,7 +20,7 @@
     bool is_clone)
     : FocusableMediaStreamTrack(execution_context,
                                 component,
-                                component->Source()->GetReadyState(),
+                                component->GetReadyState(),
                                 std::move(callback),
                                 descriptor_id,
                                 is_clone) {}
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream.cc b/third_party/blink/renderer/modules/mediastream/media_stream.cc
index 2ed33ad5..dc06ba8 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream.cc
@@ -305,7 +305,7 @@
   if (getTrackById(track->id()))
     return;
 
-  switch (track->Component()->Source()->GetType()) {
+  switch (track->Component()->GetSourceType()) {
     case MediaStreamSource::kTypeAudio:
       audio_tracks_.push_back(track);
       break;
@@ -335,7 +335,7 @@
   }
 
   wtf_size_t pos = kNotFound;
-  switch (track->Component()->Source()->GetType()) {
+  switch (track->Component()->GetSourceType()) {
     case MediaStreamSource::kTypeAudio:
       pos = audio_tracks_.Find(track);
       if (pos != kNotFound)
@@ -463,7 +463,7 @@
     return;
 
   MediaStreamTrackVector* tracks = nullptr;
-  switch (component->Source()->GetType()) {
+  switch (component->GetSourceType()) {
     case MediaStreamSource::kTypeAudio:
       tracks = &audio_tracks_;
       break;
@@ -511,7 +511,7 @@
 void MediaStream::AddTrackAndFireEvents(MediaStreamTrack* track,
                                         DispatchEventTiming event_timing) {
   DCHECK(track);
-  switch (track->Component()->Source()->GetType()) {
+  switch (track->Component()->GetSourceType()) {
     case MediaStreamSource::kTypeAudio:
       audio_tracks_.push_back(track);
       break;
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_track_impl.cc b/third_party/blink/renderer/modules/mediastream/media_stream_track_impl.cc
index d1d098a8..923709fb 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_track_impl.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_track_impl.cc
@@ -197,7 +197,7 @@
   DCHECK(!clone->GetPlatformTrack());
   DCHECK(clone->Source());
 
-  switch (clone->Source()->GetType()) {
+  switch (clone->GetSourceType()) {
     case MediaStreamSource::kTypeAudio:
       MediaStreamAudioSource::From(clone->Source())->ConnectToTrack(clone);
       break;
@@ -256,7 +256,7 @@
                                            MediaStreamComponent* component)
     : MediaStreamTrackImpl(context,
                            component,
-                           component->Source()->GetReadyState(),
+                           component->GetReadyState(),
                            /*callback=*/base::DoNothing()) {}
 
 MediaStreamTrackImpl::MediaStreamTrackImpl(ExecutionContext* context,
@@ -264,7 +264,7 @@
                                            base::OnceClosure callback)
     : MediaStreamTrackImpl(context,
                            component,
-                           component->Source()->GetReadyState(),
+                           component->GetReadyState(),
                            std::move(callback)) {}
 
 MediaStreamTrackImpl::MediaStreamTrackImpl(
@@ -286,7 +286,7 @@
   MediaStreamVideoTrack* const video_track =
       MediaStreamVideoTrack::From(Component());
   if (video_track && component_->Source() &&
-      component_->Source()->GetType() == MediaStreamSource::kTypeVideo) {
+      component_->GetSourceType() == MediaStreamSource::kTypeVideo) {
     image_capture_ = MakeGarbageCollected<ImageCapture>(
         context, this, video_track->pan_tilt_zoom_allowed(),
         std::move(callback));
@@ -311,7 +311,7 @@
   DEFINE_THREAD_SAFE_STATIC_LOCAL(String, audio_kind, ("audio"));
   DEFINE_THREAD_SAFE_STATIC_LOCAL(String, video_kind, ("video"));
 
-  switch (component_->Source()->GetType()) {
+  switch (component_->GetSourceType()) {
     case MediaStreamSource::kTypeAudio:
       return audio_kind;
     case MediaStreamSource::kTypeVideo:
@@ -327,7 +327,7 @@
 }
 
 String MediaStreamTrackImpl::label() const {
-  String label = component_->Source()->GetName();
+  String label = component_->GetSourceName();
   if (label.Contains("AirPods")) {
     label = "AirPods";
   }
@@ -366,7 +366,7 @@
       String::Format("%s({hint=%s})", __func__, hint.Utf8().c_str()));
   WebMediaStreamTrack::ContentHintType translated_hint =
       WebMediaStreamTrack::ContentHintType::kNone;
-  switch (component_->Source()->GetType()) {
+  switch (component_->GetSourceType()) {
     case MediaStreamSource::kTypeAudio:
       if (hint == kContentHintStringNone) {
         translated_hint = WebMediaStreamTrack::ContentHintType::kNone;
@@ -475,7 +475,7 @@
   if (!platform_capabilities.group_id.IsNull())
     capabilities->setGroupId(platform_capabilities.group_id);
 
-  if (component_->Source()->GetType() == MediaStreamSource::kTypeAudio) {
+  if (component_->GetSourceType() == MediaStreamSource::kTypeAudio) {
     Vector<bool> echo_cancellation, auto_gain_control, noise_suppression;
     for (bool value : platform_capabilities.echo_cancellation)
       echo_cancellation.push_back(value);
@@ -519,7 +519,7 @@
     }
   }
 
-  if (component_->Source()->GetType() == MediaStreamSource::kTypeVideo) {
+  if (component_->GetSourceType() == MediaStreamSource::kTypeVideo) {
     if (platform_capabilities.width.size() == 2) {
       LongRange* width = LongRange::Create();
       width->setMin(platform_capabilities.width[0]);
@@ -795,7 +795,7 @@
   // Note that both 'live' and 'muted' correspond to a 'live' ready state in the
   // web API, hence the following logic around |feature_handle_for_scheduler_|.
 
-  setReadyState(component_->Source()->GetReadyState());
+  setReadyState(component_->GetReadyState());
   switch (ready_state_) {
     case MediaStreamSource::kReadyStateLive:
       muted_ = false;
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc b/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc
index 175568b..35b90d1 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc
@@ -38,7 +38,7 @@
   DCHECK(!component->GetPlatformTrack());
   DCHECK(component->Source());
 
-  switch (component->Source()->GetType()) {
+  switch (component->GetSourceType()) {
     case MediaStreamSource::kTypeAudio:
       MediaStreamAudioSource::From(component->Source())
           ->ConnectToTrack(component);
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.cc b/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.cc
index 825b713..140e25c 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_renderer_sink.cc
@@ -179,7 +179,7 @@
       // Local display video rendering is considered a secure link.
       MediaStreamVideoSink::IsSecure::kYes, uses_alpha);
 
-  if (video_component_->Source()->GetReadyState() ==
+  if (video_component_->GetReadyState() ==
           MediaStreamSource::kReadyStateEnded ||
       !video_component_->Enabled()) {
     PostCrossThreadTask(
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc b/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc
index db27cc90..828e4d1 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_video_track.cc
@@ -594,7 +594,7 @@
 MediaStreamVideoTrack* MediaStreamVideoTrack::From(
     const MediaStreamComponent* component) {
   if (!component ||
-      component->Source()->GetType() != MediaStreamSource::kTypeVideo) {
+      component->GetSourceType() != MediaStreamSource::kTypeVideo) {
     return nullptr;
   }
 
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc b/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc
index 8567c72..b2253da 100644
--- a/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc
+++ b/third_party/blink/renderer/modules/mediastream/user_media_client_test.cc
@@ -131,8 +131,7 @@
                               double expected_track_frame_rate) {
   CheckVideoSource(source, expected_source_width, expected_source_height,
                    expected_source_frame_rate);
-  EXPECT_EQ(component->Source()->GetReadyState(),
-            MediaStreamSource::kReadyStateLive);
+  EXPECT_EQ(component->GetReadyState(), MediaStreamSource::kReadyStateLive);
   MediaStreamVideoTrack* track = MediaStreamVideoTrack::From(component);
   EXPECT_EQ(track->source(), source);
 
@@ -1380,8 +1379,7 @@
   source->DisableRestart();
   ApplyConstraintsVideoMode(component, 640, 480);
 
-  EXPECT_EQ(component->Source()->GetReadyState(),
-            MediaStreamSource::kReadyStateEnded);
+  EXPECT_EQ(component->GetReadyState(), MediaStreamSource::kReadyStateEnded);
   EXPECT_FALSE(source->IsRunning());
 }
 
@@ -1401,8 +1399,7 @@
   MediaStreamTrackPlatform* track =
       MediaStreamTrackPlatform::GetTrack(WebMediaStreamTrack(component));
   track->Stop();
-  EXPECT_EQ(component->Source()->GetReadyState(),
-            MediaStreamSource::kReadyStateEnded);
+  EXPECT_EQ(component->GetReadyState(), MediaStreamSource::kReadyStateEnded);
   EXPECT_FALSE(source->IsRunning());
   {
     MediaStreamTrackPlatform::Settings settings;
@@ -1413,8 +1410,7 @@
   }
 
   ApplyConstraintsVideoMode(component, 640, 480);
-  EXPECT_EQ(component->Source()->GetReadyState(),
-            MediaStreamSource::kReadyStateEnded);
+  EXPECT_EQ(component->GetReadyState(), MediaStreamSource::kReadyStateEnded);
   EXPECT_FALSE(source->IsRunning());
   {
     MediaStreamTrackPlatform::Settings settings;
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_processor.cc b/third_party/blink/renderer/modules/mediastream/user_media_processor.cc
index cd7eddc..890d8d1e 100644
--- a/third_party/blink/renderer/modules/mediastream/user_media_processor.cc
+++ b/third_party/blink/renderer/modules/mediastream/user_media_processor.cc
@@ -504,7 +504,7 @@
 void UserMediaProcessor::RequestInfo::StartAudioTrack(
     MediaStreamComponent* component,
     bool is_pending) {
-  DCHECK(component->Source()->GetType() == MediaStreamSource::kTypeAudio);
+  DCHECK(component->GetSourceType() == MediaStreamSource::kTypeAudio);
   DCHECK(request()->Audio());
 #if DCHECK_IS_ON()
   DCHECK(audio_capture_settings_.HasValue());
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
index c776f61..6079ca1 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
@@ -75,8 +75,7 @@
 
 bool IsPlayableTrack(MediaStreamComponent* component) {
   return component && component->Source() &&
-         component->Source()->GetReadyState() !=
-             MediaStreamSource::kReadyStateEnded;
+         component->GetReadyState() != MediaStreamSource::kReadyStateEnded;
 }
 
 const char* LoadTypeToString(WebMediaPlayer::LoadType type) {
@@ -530,7 +529,7 @@
         client_->AddAudioTrack(
             blink::WebString::FromUTF8(component->Id().Utf8()),
             blink::WebMediaPlayerClient::kAudioTrackKindMain,
-            blink::WebString::FromUTF8(component->Source()->GetName().Utf8()),
+            blink::WebString::FromUTF8(component->GetSourceName().Utf8()),
             /*language=*/"", is_first_audio_track);
         is_first_audio_track = false;
       }
@@ -555,7 +554,7 @@
         client_->AddVideoTrack(
             blink::WebString::FromUTF8(component->Id().Utf8()),
             blink::WebMediaPlayerClient::kVideoTrackKindMain,
-            blink::WebString::FromUTF8(component->Source()->GetName().Utf8()),
+            blink::WebString::FromUTF8(component->GetSourceName().Utf8()),
             /*language=*/"", is_first_video_track);
         is_first_video_track = false;
       }
diff --git a/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc b/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc
index be2dcf159..05334d0 100644
--- a/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc
+++ b/third_party/blink/renderer/modules/peerconnection/mock_rtc_peer_connection_handler_platform.cc
@@ -172,7 +172,7 @@
         receiver_(type),
         direction_(webrtc::RtpTransceiverDirection::kSendRecv) {
     DCHECK(!sender_.Track() ||
-           sender_.Track()->Source()->GetType() ==
+           sender_.Track()->GetSourceType() ==
                static_cast<MediaStreamSource::StreamType>(type));
   }
 
@@ -325,7 +325,7 @@
     MediaStreamComponent* component,
     const webrtc::RtpTransceiverInit&) {
   transceivers_.push_back(std::make_unique<DummyRTCRtpTransceiverPlatform>(
-      component->Source()->GetType(), component));
+      component->GetSourceType(), component));
   std::unique_ptr<DummyRTCRtpTransceiverPlatform> copy(
       new DummyRTCRtpTransceiverPlatform(*transceivers_.back()));
   return std::unique_ptr<RTCRtpTransceiverPlatform>(std::move(copy));
@@ -349,7 +349,7 @@
     MediaStreamComponent* component,
     const MediaStreamDescriptorVector&) {
   transceivers_.push_back(std::make_unique<DummyRTCRtpTransceiverPlatform>(
-      component->Source()->GetType(), component));
+      component->GetSourceType(), component));
   std::unique_ptr<DummyRTCRtpTransceiverPlatform> copy(
       new DummyRTCRtpTransceiverPlatform(*transceivers_.back()));
   return std::unique_ptr<RTCRtpTransceiverPlatform>(std::move(copy));
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
index 176e0b2..d3ae29d 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -2339,11 +2339,10 @@
 
 RTCRtpTransceiver* RTCPeerConnection::CreateOrUpdateTransceiver(
     std::unique_ptr<RTCRtpTransceiverPlatform> platform_transceiver) {
-  String kind =
-      (platform_transceiver->Receiver()->Track()->Source()->GetType() ==
-       MediaStreamSource::kTypeAudio)
-          ? "audio"
-          : "video";
+  String kind = (platform_transceiver->Receiver()->Track()->GetSourceType() ==
+                 MediaStreamSource::kTypeAudio)
+                    ? "audio"
+                    : "video";
   RTCRtpSender* sender =
       CreateOrUpdateSender(platform_transceiver->Sender(), kind);
   RTCRtpReceiver* receiver =
@@ -2600,12 +2599,12 @@
         MediaStreamTrackVector audio_tracks;
         MediaStreamComponentVector video_track_components;
         MediaStreamTrackVector video_tracks;
-        if (track->Component()->Source()->GetType() ==
+        if (track->Component()->GetSourceType() ==
             MediaStreamSource::kTypeAudio) {
           audio_track_components.push_back(track->Component());
           audio_tracks.push_back(track);
         } else {
-          DCHECK(track->Component()->Source()->GetType() ==
+          DCHECK(track->Component()->GetSourceType() ==
                  MediaStreamSource::kTypeVideo);
           video_track_components.push_back(track->Component());
           video_tracks.push_back(track);
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
index 21199ba8..73a9a30 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.cc
@@ -547,7 +547,7 @@
 
 MediaStreamTrackMetrics::Kind MediaStreamTrackMetricsKind(
     const MediaStreamComponent* component) {
-  return component->Source()->GetType() == MediaStreamSource::kTypeAudio
+  return component->GetSourceType() == MediaStreamSource::kTypeAudio
              ? MediaStreamTrackMetrics::Kind::kAudio
              : MediaStreamTrackMetrics::Kind::kVideo;
 }
@@ -2100,8 +2100,8 @@
   if (!thermal_uma_listener_) {
     // Instantiate the thermal uma listener only if we are sending video.
     for (const auto& sender : rtp_senders_) {
-      if (sender->Track() && sender->Track()->Source()->GetType() ==
-                                 MediaStreamSource::kTypeVideo) {
+      if (sender->Track() &&
+          sender->Track()->GetSourceType() == MediaStreamSource::kTypeVideo) {
         thermal_uma_listener_ = ThermalUmaListener::Create(task_runner_);
         thermal_uma_listener_->OnThermalMeasurement(last_thermal_state_);
         return;
diff --git a/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.cc b/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.cc
index 6202f304..e97cb208 100644
--- a/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.cc
+++ b/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.cc
@@ -36,10 +36,10 @@
   DCHECK(component);
   scoped_refptr<WebRtcMediaStreamTrackAdapter> local_track_adapter(
       base::AdoptRef(new WebRtcMediaStreamTrackAdapter(factory, main_thread)));
-  if (component->Source()->GetType() == MediaStreamSource::kTypeAudio) {
+  if (component->GetSourceType() == MediaStreamSource::kTypeAudio) {
     local_track_adapter->InitializeLocalAudioTrack(component);
   } else {
-    DCHECK_EQ(component->Source()->GetType(), MediaStreamSource::kTypeVideo);
+    DCHECK_EQ(component->GetSourceType(), MediaStreamSource::kTypeVideo);
     local_track_adapter->InitializeLocalVideoTrack(component);
   }
   return local_track_adapter;
@@ -114,13 +114,13 @@
     return;
   remote_track_can_complete_initialization_.Reset();
   is_disposed_ = true;
-  if (component_->Source()->GetType() == MediaStreamSource::kTypeAudio) {
+  if (component_->GetSourceType() == MediaStreamSource::kTypeAudio) {
     if (local_track_audio_sink_)
       DisposeLocalAudioTrack();
     else
       DisposeRemoteAudioTrack();
   } else {
-    DCHECK_EQ(component_->Source()->GetType(), MediaStreamSource::kTypeVideo);
+    DCHECK_EQ(component_->GetSourceType(), MediaStreamSource::kTypeVideo);
     if (local_track_video_sink_)
       DisposeLocalVideoTrack();
     else
@@ -168,7 +168,7 @@
   DCHECK(main_thread_->BelongsToCurrentThread());
   DCHECK(!is_initialized_);
   DCHECK(component);
-  DCHECK_EQ(component->Source()->GetType(), MediaStreamSource::kTypeAudio);
+  DCHECK_EQ(component->GetSourceType(), MediaStreamSource::kTypeAudio);
   SendLogMessage(base::StringPrintf("InitializeLocalAudioTrack({id=%s})",
                                     component->Id().Utf8().c_str()));
   component_ = component;
@@ -207,7 +207,7 @@
   DCHECK(main_thread_->BelongsToCurrentThread());
   DCHECK(!is_initialized_);
   DCHECK(component);
-  DCHECK_EQ(component->Source()->GetType(), MediaStreamSource::kTypeVideo);
+  DCHECK_EQ(component->GetSourceType(), MediaStreamSource::kTypeVideo);
   component_ = component;
   auto factory = factory_.Lock();
   DCHECK(factory);
@@ -308,7 +308,7 @@
 void WebRtcMediaStreamTrackAdapter::DisposeLocalAudioTrack() {
   DCHECK(main_thread_->BelongsToCurrentThread());
   DCHECK(local_track_audio_sink_);
-  DCHECK_EQ(component_->Source()->GetType(), MediaStreamSource::kTypeAudio);
+  DCHECK_EQ(component_->GetSourceType(), MediaStreamSource::kTypeAudio);
   auto* audio_track = MediaStreamAudioTrack::From(component_);
   DCHECK(audio_track);
   audio_track->RemoveSink(local_track_audio_sink_.get());
@@ -320,7 +320,7 @@
 void WebRtcMediaStreamTrackAdapter::DisposeLocalVideoTrack() {
   DCHECK(main_thread_->BelongsToCurrentThread());
   DCHECK(local_track_video_sink_);
-  DCHECK_EQ(component_->Source()->GetType(), MediaStreamSource::kTypeVideo);
+  DCHECK_EQ(component_->GetSourceType(), MediaStreamSource::kTypeVideo);
   local_track_video_sink_.reset();
   webrtc_track_ = nullptr;
   component_ = nullptr;
@@ -329,7 +329,7 @@
 void WebRtcMediaStreamTrackAdapter::DisposeRemoteAudioTrack() {
   DCHECK(main_thread_->BelongsToCurrentThread());
   DCHECK(remote_audio_track_adapter_);
-  DCHECK_EQ(component_->Source()->GetType(), MediaStreamSource::kTypeAudio);
+  DCHECK_EQ(component_->GetSourceType(), MediaStreamSource::kTypeAudio);
 
   DCHECK(webrtc_signaling_task_runner_);
   PostCrossThreadTask(
@@ -343,7 +343,7 @@
 void WebRtcMediaStreamTrackAdapter::DisposeRemoteVideoTrack() {
   DCHECK(main_thread_->BelongsToCurrentThread());
   DCHECK(remote_video_track_adapter_);
-  DCHECK_EQ(component_->Source()->GetType(), MediaStreamSource::kTypeVideo);
+  DCHECK_EQ(component_->GetSourceType(), MediaStreamSource::kTypeVideo);
   FinalizeRemoteTrackDisposingOnMainThread();
 }
 
diff --git a/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_test.cc b/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_test.cc
index 826accee..9c235bc 100644
--- a/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_test.cc
+++ b/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_test.cc
@@ -126,7 +126,7 @@
           dependency_factory_.Get(), main_thread_, CreateLocalAudioTrack());
   EXPECT_TRUE(track_adapter_->is_initialized());
   EXPECT_TRUE(track_adapter_->track());
-  EXPECT_EQ(track_adapter_->track()->Source()->GetType(),
+  EXPECT_EQ(track_adapter_->track()->GetSourceType(),
             MediaStreamSource::kTypeAudio);
   EXPECT_TRUE(track_adapter_->webrtc_track());
   EXPECT_EQ(track_adapter_->webrtc_track()->kind(),
@@ -146,7 +146,7 @@
           dependency_factory_.Get(), main_thread_, CreateLocalVideoTrack());
   EXPECT_TRUE(track_adapter_->is_initialized());
   EXPECT_TRUE(track_adapter_->track());
-  EXPECT_EQ(track_adapter_->track()->Source()->GetType(),
+  EXPECT_EQ(track_adapter_->track()->GetSourceType(),
             MediaStreamSource::kTypeVideo);
   EXPECT_TRUE(track_adapter_->webrtc_track());
   EXPECT_EQ(track_adapter_->webrtc_track()->kind(),
@@ -172,7 +172,7 @@
   DCHECK(track_adapter_);
   EXPECT_TRUE(track_adapter_->is_initialized());
   EXPECT_TRUE(track_adapter_->track());
-  EXPECT_EQ(track_adapter_->track()->Source()->GetType(),
+  EXPECT_EQ(track_adapter_->track()->GetSourceType(),
             MediaStreamSource::kTypeAudio);
   EXPECT_TRUE(track_adapter_->webrtc_track());
   EXPECT_EQ(track_adapter_->webrtc_track()->kind(),
@@ -197,7 +197,7 @@
   DCHECK(track_adapter_);
   EXPECT_TRUE(track_adapter_->is_initialized());
   EXPECT_TRUE(track_adapter_->track());
-  EXPECT_EQ(track_adapter_->track()->Source()->GetType(),
+  EXPECT_EQ(track_adapter_->track()->GetSourceType(),
             MediaStreamSource::kTypeVideo);
   EXPECT_TRUE(track_adapter_->webrtc_track());
   EXPECT_EQ(track_adapter_->webrtc_track()->kind(),
@@ -226,7 +226,7 @@
   track_adapter_->InitializeOnMainThread();
   EXPECT_TRUE(track_adapter_->is_initialized());
   EXPECT_TRUE(track_adapter_->track());
-  EXPECT_EQ(track_adapter_->track()->Source()->GetType(),
+  EXPECT_EQ(track_adapter_->track()->GetSourceType(),
             MediaStreamSource::kTypeAudio);
   EXPECT_TRUE(track_adapter_->webrtc_track());
   EXPECT_EQ(track_adapter_->webrtc_track()->kind(),
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.cc b/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.cc
index ba3f5eda..60074d0 100644
--- a/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.cc
+++ b/third_party/blink/renderer/platform/mediastream/media_stream_audio_track.cc
@@ -40,7 +40,7 @@
 MediaStreamAudioTrack* MediaStreamAudioTrack::From(
     const MediaStreamComponent* component) {
   if (!component ||
-      component->Source()->GetType() != MediaStreamSource::kTypeAudio) {
+      component->GetSourceType() != MediaStreamSource::kTypeAudio) {
     return nullptr;
   }
   return static_cast<MediaStreamAudioTrack*>(component->GetPlatformTrack());
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_component.h b/third_party/blink/renderer/platform/mediastream/media_stream_component.h
index 2bbb7af..d44e699 100644
--- a/third_party/blink/renderer/platform/mediastream/media_stream_component.h
+++ b/third_party/blink/renderer/platform/mediastream/media_stream_component.h
@@ -38,6 +38,7 @@
 #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
 #include "third_party/blink/renderer/platform/heap/prefinalizer.h"
 #include "third_party/blink/renderer/platform/mediastream/media_constraints.h"
+#include "third_party/blink/renderer/platform/mediastream/media_stream_source.h"
 #include "third_party/blink/renderer/platform/mediastream/media_stream_track_platform.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
@@ -64,6 +65,9 @@
   virtual String Id() const = 0;
   // Uniquely identifies this component.
   virtual int UniqueId() const = 0;
+  virtual MediaStreamSource::StreamType GetSourceType() const = 0;
+  virtual const String& GetSourceName() const = 0;
+  virtual MediaStreamSource::ReadyState GetReadyState() const = 0;
   virtual bool Remote() const = 0;
   virtual bool Enabled() const = 0;
   virtual void SetEnabled(bool enabled) = 0;
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_component_impl.cc b/third_party/blink/renderer/platform/mediastream/media_stream_component_impl.cc
index 116738b..2311036 100644
--- a/third_party/blink/renderer/platform/mediastream/media_stream_component_impl.cc
+++ b/third_party/blink/renderer/platform/mediastream/media_stream_component_impl.cc
@@ -137,12 +137,12 @@
       break;
     case WebMediaStreamTrack::ContentHintType::kAudioSpeech:
     case WebMediaStreamTrack::ContentHintType::kAudioMusic:
-      DCHECK_EQ(MediaStreamSource::kTypeAudio, Source()->GetType());
+      DCHECK_EQ(MediaStreamSource::kTypeAudio, GetSourceType());
       break;
     case WebMediaStreamTrack::ContentHintType::kVideoMotion:
     case WebMediaStreamTrack::ContentHintType::kVideoDetail:
     case WebMediaStreamTrack::ContentHintType::kVideoText:
-      DCHECK_EQ(MediaStreamSource::kTypeVideo, Source()->GetType());
+      DCHECK_EQ(MediaStreamSource::kTypeVideo, GetSourceType());
       break;
   }
   if (hint == content_hint_)
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_component_impl.h b/third_party/blink/renderer/platform/mediastream/media_stream_component_impl.h
index 1e3d99a..c0b15767 100644
--- a/third_party/blink/renderer/platform/mediastream/media_stream_component_impl.h
+++ b/third_party/blink/renderer/platform/mediastream/media_stream_component_impl.h
@@ -82,6 +82,13 @@
 
   String Id() const override { return id_; }
   int UniqueId() const override { return unique_id_; }
+  MediaStreamSource::StreamType GetSourceType() const override {
+    return Source()->GetType();
+  }
+  const String& GetSourceName() const override { return Source()->GetName(); }
+  MediaStreamSource::ReadyState GetReadyState() const override {
+    return Source()->GetReadyState();
+  }
   bool Remote() const override { return Source()->Remote(); }
   bool Enabled() const override { return enabled_; }
   void SetEnabled(bool enabled) override { enabled_ = enabled; }
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.cc b/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.cc
index bcc3c12..dfc15277 100644
--- a/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.cc
+++ b/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.cc
@@ -51,7 +51,7 @@
 }
 
 void MediaStreamDescriptor::AddComponent(MediaStreamComponent* component) {
-  switch (component->Source()->GetType()) {
+  switch (component->GetSourceType()) {
     case MediaStreamSource::kTypeAudio:
       if (audio_components_.Find(component) == kNotFound)
         audio_components_.push_back(component);
@@ -70,7 +70,7 @@
 
 void MediaStreamDescriptor::RemoveComponent(MediaStreamComponent* component) {
   wtf_size_t pos = kNotFound;
-  switch (component->Source()->GetType()) {
+  switch (component->GetSourceType()) {
     case MediaStreamSource::kTypeAudio:
       pos = audio_components_.Find(component);
       if (pos != kNotFound)
diff --git a/third_party/blink/renderer/platform/mediastream/transferred_media_stream_component.cc b/third_party/blink/renderer/platform/mediastream/transferred_media_stream_component.cc
index 14ce4e8..b2200b4 100644
--- a/third_party/blink/renderer/platform/mediastream/transferred_media_stream_component.cc
+++ b/third_party/blink/renderer/platform/mediastream/transferred_media_stream_component.cc
@@ -48,6 +48,32 @@
   return 0;
 }
 
+MediaStreamSource::StreamType TransferredMediaStreamComponent::GetSourceType()
+    const {
+  if (component_) {
+    return component_->GetSourceType();
+  }
+  // TODO(crbug.com/1288839): Return the transferred value
+  return MediaStreamSource::StreamType::kTypeVideo;
+}
+const String& TransferredMediaStreamComponent::GetSourceName() const {
+  if (component_) {
+    return component_->GetSourceName();
+  }
+  // TODO(crbug.com/1288839): Return the transferred value
+  static String name;
+  return name;
+}
+
+MediaStreamSource::ReadyState TransferredMediaStreamComponent::GetReadyState()
+    const {
+  if (component_) {
+    return component_->GetReadyState();
+  }
+  // TODO(crbug.com/1288839): Return the transferred value
+  return MediaStreamSource::ReadyState::kReadyStateEnded;
+}
+
 bool TransferredMediaStreamComponent::Remote() const {
   if (component_) {
     return component_->Remote();
diff --git a/third_party/blink/renderer/platform/mediastream/transferred_media_stream_component.h b/third_party/blink/renderer/platform/mediastream/transferred_media_stream_component.h
index 4b28471..e15c15d6 100644
--- a/third_party/blink/renderer/platform/mediastream/transferred_media_stream_component.h
+++ b/third_party/blink/renderer/platform/mediastream/transferred_media_stream_component.h
@@ -45,6 +45,9 @@
 
   String Id() const override;
   int UniqueId() const override;
+  MediaStreamSource::StreamType GetSourceType() const override;
+  const String& GetSourceName() const override;
+  MediaStreamSource::ReadyState GetReadyState() const override;
   bool Remote() const override;
   bool Enabled() const override;
   void SetEnabled(bool enabled) override;
diff --git a/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility b/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility
index d13d2173..cac050e 100644
--- a/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility
+++ b/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility
@@ -106,3 +106,7 @@
 wpt_internal/webcodecs/annexb_decoding.https.any.worker.html [ Skip ]
 wpt_internal/webcodecs/avc_encoder_config.https.any.html [ Skip ]
 wpt_internal/webcodecs/avc_encoder_config.https.any.worker.html [ Skip ]
+
+# Most likely a forced style/layout update from accessibiity while we are
+# render blocking, which should not happen.
+crbug.com/1351811 external/wpt/css/css-transitions/no-transition-from-ua-to-blocking-stylesheet.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 6c6473c..0572745e9 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -7091,3 +7091,6 @@
 crbug.com/1350336 [ Mac ] virtual/fenced-frame-mparch/wpt_internal/fenced_frame/visual-viewport.https.html [ Failure Pass ]
 crbug.com/1350337 [ Linux ] external/wpt/web-locks/query-ordering.tentative.https.html [ Failure Pass ]
 crbug.com/1350341 [ Linux ] virtual/threaded-no-composited-antialiasing/animations/direction-and-fill/fill-mode-missing-from-to-keyframes.html [ Failure Pass ]
+
+# TODO(crbug.com/1352009): Research how to re-enable test once not flaky
+crbug.com/1352009 external/wpt/preload/preconnect.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/external/wpt/fs/FileSystemSyncAccessHandle-read-write.https.tentative.worker.js b/third_party/blink/web_tests/external/wpt/fs/FileSystemSyncAccessHandle-read-write.https.tentative.worker.js
index 9f2a61d..cdefc78b6 100644
--- a/third_party/blink/web_tests/external/wpt/fs/FileSystemSyncAccessHandle-read-write.https.tentative.worker.js
+++ b/third_party/blink/web_tests/external/wpt/fs/FileSystemSyncAccessHandle-read-write.https.tentative.worker.js
@@ -13,7 +13,7 @@
   if (!('TextEncoder' in self)) {
     return;
   }
-  const encoder = new TextEncoder();
+
   const decoder = new TextDecoder();
 
   const text = 'Hello Storage Foundation';
@@ -26,7 +26,7 @@
   let readBytes = handle.read(readBuffer, {at: 0});
   assert_equals(writtenBytes, readBytes, 'Check that all bytes were read');
   assert_equals(
-      text, new TextDecoder().decode(readBuffer),
+      text, decoder.decode(readBuffer),
       'Check that the written bytes and the read bytes match');
 
   // Test a read of less bytes than available.
@@ -34,7 +34,7 @@
   readBuffer = new Uint8Array(expected.length);
   readBytes = handle.read(readBuffer, {at: text.indexOf(expected)});
   assert_equals(readBuffer.length, readBytes, 'Check that all bytes were read');
-  const actual = new TextDecoder().decode(readBuffer);
+  const actual = decoder.decode(readBuffer);
   assert_equals(
       expected, actual,
       'Partial read returned unexpected contents');
@@ -49,7 +49,7 @@
   const decoder = new TextDecoder();
 
   for (text of ['Hello', 'Longer Text']) {
-    const writeBuffer = new TextEncoder().encode(text);
+    const writeBuffer = encoder.encode(text);
     const writtenBytes = handle.write(writeBuffer, {at: 0});
     assert_equals(
         writeBuffer.byteLength, writtenBytes,
@@ -58,7 +58,7 @@
     const readBytes = handle.read(readBuffer, {at: 0});
     assert_equals(writtenBytes, readBytes, 'Check that all bytes were read');
     assert_equals(
-        text, new TextDecoder().decode(readBuffer),
+        text, decoder.decode(readBuffer),
         'Check that the written bytes and the read bytes match');
   }
 }, 'Test second write that is bigger than the first write');
@@ -76,7 +76,7 @@
                {input: 'foobar', expected: 'foobarWorld'}]) {
     const text = tuple.input;
     const expected = tuple.expected;
-    const writeBuffer = new TextEncoder().encode(text);
+    const writeBuffer = encoder.encode(text);
     const writtenBytes = handle.write(writeBuffer, {at: 0});
     assert_equals(
         writeBuffer.byteLength, writtenBytes,
@@ -85,7 +85,7 @@
     const readBytes = handle.read(readBuffer, {at: 0});
     assert_equals(expected.length, readBytes, 'Check that all bytes were read');
     assert_equals(
-        expected, new TextDecoder().decode(readBuffer),
+        expected, decoder.decode(readBuffer),
         'Check that the written bytes and the read bytes match');
   }
 }, 'Test second write that is smaller than the first write');
@@ -118,6 +118,7 @@
   if (!('TextEncoder' in self)) {
     return;
   }
+
   const encoder = new TextEncoder();
   const decoder = new TextDecoder();
 
@@ -127,7 +128,7 @@
     const text = tuple.input;
     const expected = tuple.expected;
     const offset = tuple.offset;
-    const writeBuffer = new TextEncoder().encode(text);
+    const writeBuffer = encoder.encode(text);
     const writtenBytes = handle.write(writeBuffer, {at: offset});
     assert_equals(
         writeBuffer.byteLength, writtenBytes,
@@ -135,7 +136,7 @@
     const readBuffer = new Uint8Array(expected.length);
     const readBytes = handle.read(readBuffer, {at: 0});
     assert_equals(expected.length, readBytes, 'Check that all bytes were read');
-    const actual = new TextDecoder().decode(readBuffer);
+    const actual = decoder.decode(readBuffer);
     assert_equals(
         expected, actual,
         'Check content read from the handle');
@@ -146,7 +147,7 @@
   if (!('TextEncoder' in self)) {
     return;
   }
-  const encoder = new TextEncoder();
+
   const decoder = new TextDecoder();
 
   const text = 'Hello Storage Foundation';
@@ -165,7 +166,7 @@
     const readBuffer = new Uint8Array(bufferLength);
     const readBytes = handle.read(readBuffer, {at: offset});
     assert_equals(expected.length, readBytes, 'Check that all bytes were read');
-    const actual = new TextDecoder().decode(readBuffer);
+    const actual = decoder.decode(readBuffer);
     assert_true(
         actual.startsWith(expected),
         `Expected to read ${expected} but the actual value was ${actual}.`);
@@ -181,6 +182,52 @@
 }, 'Test read at an offset');
 
 sync_access_handle_test((t, handle) => {
+  if (!('TextEncoder' in self)) {
+    return;
+  }
+
+  const expected = 'Hello Storage Foundation';
+  const writeBuffer = new TextEncoder().encode(expected);
+  const writtenBytes = handle.write(writeBuffer, {at: 0});
+  assert_equals(
+      writeBuffer.byteLength, writtenBytes,
+      'Check that all bytes were written.');
+
+  const bufferLength = expected.length;
+  const readBuffer = new Uint8Array(expected.length);
+  // No options parameter provided, should read at offset 0.
+  const readBytes = handle.read(readBuffer);
+  assert_equals(expected.length, readBytes, 'Check that all bytes were read');
+  const actual = new TextDecoder().decode(readBuffer);
+  assert_equals(
+      expected, actual,
+      `Expected to read ${expected} but the actual value was ${actual}.`);
+}, 'Test read with default options');
+
+sync_access_handle_test((t, handle) => {
+  if (!('TextEncoder' in self)) {
+    return;
+  }
+
+  const expected = 'Hello Storage Foundation';
+  const writeBuffer = new TextEncoder().encode(expected);
+  // No options parameter provided, should write at offset 0.
+  const writtenBytes = handle.write(writeBuffer);
+  assert_equals(
+      writeBuffer.byteLength, writtenBytes,
+      'Check that all bytes were written.');
+
+  const bufferLength = expected.length;
+  const readBuffer = new Uint8Array(expected.length);
+  const readBytes = handle.read(readBuffer, {at: 0});
+  assert_equals(expected.length, readBytes, 'Check that all bytes were read');
+  const actual = new TextDecoder().decode(readBuffer);
+  assert_equals(
+      expected, actual,
+      `Expected to read ${expected} but the actual value was ${actual}.`);
+}, 'Test write with default options');
+
+sync_access_handle_test((t, handle) => {
   const readBuffer = new Uint8Array(24);
   assert_throws_js(TypeError, () => handle.read(readBuffer, {at: -1}));
 }, 'Test reading at a negative offset fails.');
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/css/css-contain/container-queries/custom-property-style-queries-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/css/css-contain/container-queries/custom-property-style-queries-expected.txt
deleted file mode 100644
index c2a1b04..0000000
--- a/third_party/blink/web_tests/platform/generic/external/wpt/css/css-contain/container-queries/custom-property-style-queries-expected.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-This is a testharness.js-based test.
-FAIL style(--inner: true) assert_equals: expected "true" but got ""
-FAIL style(--inner:true) assert_equals: expected "true" but got ""
-FAIL style(--inner:true ) assert_equals: expected "true" but got ""
-FAIL style(--inner: true ) assert_equals: expected "true" but got ""
-PASS style(--inner-no-space: true)
-PASS style(--inner-no-space:true)
-FAIL style(--inner-no-space:true ) assert_equals: expected "true" but got ""
-FAIL style(--inner-no-space: true ) assert_equals: expected "true" but got ""
-FAIL style(--inner-space-after: true) assert_equals: expected "true" but got ""
-FAIL style(--inner-space-after:true) assert_equals: expected "true" but got ""
-PASS style(--inner-space-after:true )
-PASS style(--inner-space-after: true )
-PASS style(--outer: true)
-PASS style(--outer:true)
-PASS style(--outer:true )
-PASS style(--outer: true )
-PASS style(--outer-no-space: true)
-PASS style(--outer-no-space:true)
-PASS style(--outer-no-space:true )
-PASS style(--outer-no-space: true )
-PASS style(--outer-space-after: true)
-PASS style(--outer-space-after:true)
-PASS style(--outer-space-after:true )
-PASS style(--outer-space-after: true )
-PASS outer style(--inner: true)
-PASS outer style(--inner:true)
-PASS outer style(--inner:true )
-PASS outer style(--inner: true )
-PASS outer style(--inner-no-space: true)
-PASS outer style(--inner-no-space:true)
-PASS outer style(--inner-no-space:true )
-PASS outer style(--inner-no-space: true )
-PASS outer style(--inner-space-after: true)
-PASS outer style(--inner-space-after:true)
-PASS outer style(--inner-space-after:true )
-PASS outer style(--inner-space-after: true )
-FAIL outer style(--outer: true) assert_equals: expected "true" but got ""
-FAIL outer style(--outer:true) assert_equals: expected "true" but got ""
-FAIL outer style(--outer:true ) assert_equals: expected "true" but got ""
-FAIL outer style(--outer: true ) assert_equals: expected "true" but got ""
-PASS outer style(--outer-no-space: true)
-PASS outer style(--outer-no-space:true)
-FAIL outer style(--outer-no-space:true ) assert_equals: expected "true" but got ""
-FAIL outer style(--outer-no-space: true ) assert_equals: expected "true" but got ""
-FAIL outer style(--outer-space-after: true) assert_equals: expected "true" but got ""
-FAIL outer style(--outer-space-after:true) assert_equals: expected "true" but got ""
-PASS outer style(--outer-space-after:true )
-PASS outer style(--outer-space-after: true )
-Harness: the test ran to completion.
-
diff --git a/third_party/nearby/README.chromium b/third_party/nearby/README.chromium
index fa244f6..ad185d5 100644
--- a/third_party/nearby/README.chromium
+++ b/third_party/nearby/README.chromium
@@ -1,7 +1,7 @@
 Name: Nearby Connections Library
 Short Name: Nearby
 URL: https://github.com/google/nearby
-Version: c48e27d754b4a72508519838d72a7d143accc0f6
+Version: 30a82350cdda38c01fd6794d9addee89ced7d10f
 License: Apache 2.0
 License File: LICENSE
 Security Critical: yes
diff --git a/third_party/wayland-protocols/README.chromium b/third_party/wayland-protocols/README.chromium
index 67670f6b..c686aaec 100644
--- a/third_party/wayland-protocols/README.chromium
+++ b/third_party/wayland-protocols/README.chromium
@@ -1,6 +1,6 @@
 Name: wayland-protocols
 URL: http://wayland.freedesktop.org/
-Version: 1.21
+Version: 1.26
 License: MIT
 License File: src/COPYING
 Security Critical: yes
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 0efe39f..3c010de 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -63,6 +63,14 @@
   <int value="4" label="kNotAllowedToShow"/>
 </enum>
 
+<enum name="AboutThisSiteInteraction">
+  <int value="0" label="kNotShown"/>
+  <int value="1" label="kShownWithDescription"/>
+  <int value="2" label="kShownWithoutDescription"/>
+  <int value="3" label="kClickedWithDescription"/>
+  <int value="4" label="kClickedWithoutDescription"/>
+</enum>
+
 <enum name="AboutThisSiteStatus">
   <summary>Tracks status of AboutThisSite queries.</summary>
   <int value="0" label="kValid">A valid response.</int>
@@ -1597,6 +1605,13 @@
   <int value="5" label="InferenceExecutionFailed"/>
 </enum>
 
+<enum name="AliveAfterApiNotConnectedStatus">
+  <int value="0" label="Alive on receiving the error, this is always reported"/>
+  <int value="1"
+      label="Alive after a delay, Chrome didn't shutdown/restart since
+             receiving the error"/>
+</enum>
+
 <enum name="AllowedUsersPoliciesInvalidState">
   <summary>
     For recording which of the 4 disallowed combinations of allow_new_users and
@@ -2941,6 +2956,9 @@
       label="WEB_SETTINGS_GET_ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY_ENABLED">
     WebSettingsCompat#getEnterpriseAuthenticationAppLinkPolicyEnabled()
   </int>
+  <int value="63" label="WEB_View_COOKIE_MANAGER_GET_COOKIE_INFO">
+    CookieManagerCompat#getCookieInfo()
+  </int>
 </enum>
 
 <enum name="AnnouncementNotificationEvent">
@@ -10859,6 +10877,7 @@
   <int value="4" label="Account chooser dialog"/>
   <int value="5" label="Password check - Automated password change"/>
   <int value="6" label="Incognito reauthentication flow"/>
+  <int value="7" label="Passwords in settings"/>
 </enum>
 
 <enum name="BiometricAuthResult">
@@ -27388,13 +27407,13 @@
 <enum name="DownloadBubbleSubpageAction">
   <int value="0" label="Subpage shown"/>
   <int value="1" label="Checkbox shown"/>
-  <int value="2" label="First Button shown"/>
-  <int value="3" label="Second Button shown"/>
+  <int value="2" label="Secondary Button shown"/>
+  <int value="3" label="Primary Button shown"/>
   <int value="4" label="Back button pressed"/>
   <int value="5" label="Subpage closed"/>
   <int value="6" label="Checkbox clicked"/>
-  <int value="7" label="First button pressed"/>
-  <int value="8" label="Second button pressed"/>
+  <int value="7" label="Secondary button pressed"/>
+  <int value="8" label="Primary button pressed"/>
 </enum>
 
 <enum name="DownloadCalendarFileUI">
@@ -40995,6 +41014,7 @@
   <int value="4326" label="V8PendingPostBeacon_Constructor"/>
   <int value="4327" label="V8PendingPostBeacon_SetData_Method"/>
   <int value="4328" label="ContentVisibilityAutoStateChangedHandlerRegistered"/>
+  <int value="4329" label="ReplacedElementPaintedWithLargeOverflow"/>
 </enum>
 
 <enum name="FeaturePolicyAllowlistType">
diff --git a/tools/metrics/histograms/metadata/autofill/histograms.xml b/tools/metrics/histograms/metadata/autofill/histograms.xml
index da8d1d1..e9e3d82 100644
--- a/tools/metrics/histograms/metadata/autofill/histograms.xml
+++ b/tools/metrics/histograms/metadata/autofill/histograms.xml
@@ -1906,12 +1906,13 @@
 </histogram>
 
 <histogram name="Autofill.LabelInference.AssignedLabelSource"
-    enum="AssignedLabelSource" expires_after="2022-09-01">
+    enum="AssignedLabelSource" expires_after="2022-10-15">
   <owner>fleimgruber@google.com</owner>
   <owner>chrome-autofill-team@google.com</owner>
   <summary>
-    Logs how a label for=x element was assigned to an input. Emitted during
-    label inference.
+    Logs how a label for=x element was assigned to an input. Emitted once per
+    inferred label (and thus potentially multiple times per field) during label
+    inference.
   </summary>
 </histogram>
 
diff --git a/tools/metrics/histograms/metadata/download/histograms.xml b/tools/metrics/histograms/metadata/download/histograms.xml
index 54370e9..66c9877 100644
--- a/tools/metrics/histograms/metadata/download/histograms.xml
+++ b/tools/metrics/histograms/metadata/download/histograms.xml
@@ -120,7 +120,7 @@
 </histogram>
 
 <histogram
-    name="Download.Bubble.Subpage.{DownloadDangerTypeString}.{ButtonNum}ButtonActionTime"
+    name="Download.Bubble.Subpage.{DownloadDangerTypeString}.{ButtonType}ButtonActionTime"
     units="ms" expires_after="2022-10-18">
   <owner>bhatiarohit@google.com</owner>
   <owner>chrome-counter-abuse-alerts@google.com</owner>
@@ -129,11 +129,13 @@
     shown, and one of the buttons being acted upon. The warning subpage is shown
     when the user sees a download warning on the full or the partial view, and
     navigates to the subpage for more actions. Recorded only for Desktop
-    platforms, where Download Bubble is enabled.
+    platforms, where Download Bubble is enabled. In M105, FirstButtonActionTime
+    is replaced with SecondaryButtonActionTime, SecondButtonActionTime is
+    replaced with PrimaryButtonActionTime.
   </summary>
-  <token key="ButtonNum">
-    <variant name="First"/>
-    <variant name="Second"/>
+  <token key="ButtonType">
+    <variant name="Primary"/>
+    <variant name="Secondary"/>
   </token>
   <token key="DownloadDangerTypeString" variants="DownloadDangerTypeString"/>
 </histogram>
@@ -554,7 +556,7 @@
 </histogram>
 
 <histogram name="Download.IOSDownloadPassKitResult"
-    enum="DownloadPassKitResult" expires_after="2022-08-14">
+    enum="DownloadPassKitResult" expires_after="2023-02-14">
   <owner>sdefresne@chromium.org</owner>
   <owner>ewannpv@chromium.org</owner>
   <owner>mrefaat@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml
index b6c1027ba..c24ab9e 100644
--- a/tools/metrics/histograms/metadata/media/histograms.xml
+++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -690,7 +690,7 @@
 </histogram>
 
 <histogram name="Media.Audio.Output.Win.{AudioOutputMethod}Error"
-    enum="Hresult" expires_after="M107">
+    enum="Hresult" expires_after="M113">
   <owner>dalecurtis@chromium.org</owner>
   <owner>media-dev@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml
index 2c1c65f..9338a279 100644
--- a/tools/metrics/histograms/metadata/others/histograms.xml
+++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -7189,7 +7189,7 @@
 </histogram>
 
 <histogram name="Kiosk.Extensions.InstallDuration" units="ms"
-    expires_after="2022-09-01">
+    expires_after="2023-08-10">
   <owner>yixie@chromium.org</owner>
   <owner>chromeos-kiosk-eng@google.com</owner>
   <summary>
@@ -7213,7 +7213,7 @@
 </histogram>
 
 <histogram name="Kiosk.Extensions.InstallTimedOut" enum="BooleanYesNo"
-    expires_after="2022-09-01">
+    expires_after="2023-08-10">
   <owner>yixie@chromium.org</owner>
   <owner>chromeos-kiosk-eng@google.com</owner>
   <summary>
@@ -7241,7 +7241,7 @@
 </histogram>
 
 <histogram name="Kiosk.LaunchDuration.{KioskType}" units="ms"
-    expires_after="2022-09-20">
+    expires_after="2023-08-10">
   <owner>yixie@chromium.org</owner>
   <owner>chromeos-kiosk-eng@google.com</owner>
   <summary>Records the total duration it takes to launch a kiosk app.</summary>
diff --git a/tools/metrics/histograms/metadata/password/histograms.xml b/tools/metrics/histograms/metadata/password/histograms.xml
index 5e1d494..4c7d9769 100644
--- a/tools/metrics/histograms/metadata/password/histograms.xml
+++ b/tools/metrics/histograms/metadata/password/histograms.xml
@@ -729,6 +729,20 @@
   </summary>
 </histogram>
 
+<histogram name="PasswordManager.AliveAfterApiNotConnectedError"
+    enum="AliveAfterApiNotConnectedStatus" expires_after="M108">
+  <owner>vasilii@chromium.org</owner>
+  <owner>maxan@google.com</owner>
+  <summary>
+    Recorded after PasswordStore GMS Core backend returned with
+    API_NOT_CONNECTED error. The first status is reported right after receiving
+    the error, the second one is reported with a 10 seconds delay indicating if
+    Chrome didn't shutdown/restart soon after receiving this error. Note that
+    the second status could also be not reported if Chrome is sent to
+    background.
+  </summary>
+</histogram>
+
 <histogram name="PasswordManager.Android.PasswordCredentialEntry"
     enum="PasswordManagerAndroidPasswordEntryActions" expires_after="M95">
   <obsolete>
@@ -886,17 +900,6 @@
   </summary>
 </histogram>
 
-<histogram name="PasswordManager.BiometricAuthPwdFill.AuthRequester"
-    enum="BiometricAuthRequester" expires_after="2022-12-11">
-  <owner>ioanap@chromium.org</owner>
-  <owner>fhorschig@chromium.org</owner>
-  <summary>
-    Recorded when a password filling surface or the account chooser dialog
-    requests to re-auth the user via biometrics. It records the UI surface that
-    made the request.
-  </summary>
-</histogram>
-
 <histogram name="PasswordManager.BiometricAuthPwdFill.AuthResult"
     enum="BiometricAuthResult" expires_after="2022-12-11">
   <owner>ioanap@chromium.org</owner>
@@ -2062,7 +2065,7 @@
   <owner>maxan@google.com</owner>
   <summary>
     Records the time(ms) elapsed between asking Google Play Services to
-    {Operation} and recieving the error response. This is recorded either before
+    {Operation} and receiving the error response. This is recorded either before
     making the actual request (if the preconditions are not met) or after the
     asynchronous call comes back with an error. This is currently only recorded
     on Android.
@@ -2077,7 +2080,7 @@
   <owner>maxan@google.com</owner>
   <summary>
     Records the time(ms) elapsed between asking Google Play Services to
-    {Operation} and recieving the response. It includes synchronous calls made
+    {Operation} and receiving the response. It includes synchronous calls made
     to get the PasswordCheckupClient. Recorded when the asynchronous call comes
     back and only on success. This is currently only recorded on Android.
   </summary>
diff --git a/tools/metrics/histograms/metadata/security/histograms.xml b/tools/metrics/histograms/metadata/security/histograms.xml
index ef95c64..caff419 100644
--- a/tools/metrics/histograms/metadata/security/histograms.xml
+++ b/tools/metrics/histograms/metadata/security/histograms.xml
@@ -210,6 +210,16 @@
   </summary>
 </histogram>
 
+<histogram name="Security.PageInfo.AboutThisSiteInteraction"
+    enum="AboutThisSiteInteraction" expires_after="2022-12-18">
+  <owner>dullweber@chromium.org</owner>
+  <owner>olesiamarukhno@chromium.org</owner>
+  <summary>
+    Tracks interactions with the AboutThisSite feature. Recorded when PageInfo
+    is opened and when the user interacts with the AboutThisSite row.
+  </summary>
+</histogram>
+
 <histogram name="Security.PageInfo.AboutThisSiteLanguageSupported"
     enum="Boolean" expires_after="M109">
   <owner>dullweber@chromium.org</owner>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index e87b080..687c3c54 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -15788,6 +15788,21 @@
   </metric>
 </event>
 
+<event name="PasswordManager.PasswordFillingIOS">
+  <owner>theocristea@google.com</owner>
+  <owner>kazinova@google.com</owner>
+  <owner>vsemeniuk@google.com</owner>
+  <summary>
+    Records password filling for IOS. The metric records whether the password
+    filling is successful upon suggestion click.
+  </summary>
+  <metric name="FillingSuccess" enum="BooleanSuccess">
+    <summary>
+      A boolean indicating success or failure.
+    </summary>
+  </metric>
+</event>
+
 <event name="PasswordManager.WellKnownChangePasswordResult">
   <owner>kazinova@google.com</owner>
   <owner>vasilii@chromium.org</owner>
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc
index c4613c1..733e57c 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.cc
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -613,10 +613,6 @@
       obj->GetDelegate()->GetSupportedActions();
   g_return_val_if_fail(index < static_cast<gint>(actions.size()), FALSE);
 
-  if (index == 0 && obj->GetDelegate()->HasDefaultActionVerb()) {
-    // If there is a default action, it will always be at index 0.
-    return obj->DoDefaultAction();
-  }
   AXActionData data;
   data.action = actions[index];
   return obj->GetDelegate()->AccessibilityPerformAction(data);
@@ -4625,12 +4621,6 @@
   return false;
 }
 
-bool AXPlatformNodeAuraLinux::DoDefaultAction() {
-  AXActionData action_data;
-  action_data.action = ax::mojom::Action::kDoDefault;
-  return delegate_->AccessibilityPerformAction(action_data);
-}
-
 const gchar* AXPlatformNodeAuraLinux::GetDefaultActionName() {
   int action;
   if (!GetIntAttribute(ax::mojom::IntAttribute::kDefaultActionVerb, &action))
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.h b/ui/accessibility/platform/ax_platform_node_auralinux.h
index 3766b30..1635ac8 100644
--- a/ui/accessibility/platform/ax_platform_node_auralinux.h
+++ b/ui/accessibility/platform/ax_platform_node_auralinux.h
@@ -154,7 +154,6 @@
   bool GrabFocusOrSetSequentialFocusNavigationStartingPointAtOffset(int offset);
   bool GrabFocusOrSetSequentialFocusNavigationStartingPoint();
   bool SetSequentialFocusNavigationStartingPoint();
-  bool DoDefaultAction();
   const gchar* GetDefaultActionName();
   AtkAttributeSet* GetAtkAttributes();
 
diff --git a/ui/ozone/platform/wayland/host/wayland_connection.cc b/ui/ozone/platform/wayland/host/wayland_connection.cc
index e3058a7..ae6846d 100644
--- a/ui/ozone/platform/wayland/host/wayland_connection.cc
+++ b/ui/ozone/platform/wayland/host/wayland_connection.cc
@@ -75,7 +75,7 @@
 // advertised by the server.
 constexpr uint32_t kMaxCompositorVersion = 4;
 constexpr uint32_t kMaxKeyboardExtensionVersion = 2;
-constexpr uint32_t kMaxXdgShellVersion = 3;
+constexpr uint32_t kMaxXdgShellVersion = 5;
 constexpr uint32_t kMaxZXdgShellVersion = 1;
 constexpr uint32_t kMaxWpPresentationVersion = 1;
 constexpr uint32_t kMaxWpViewporterVersion = 1;
diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc
index b9df189..f4e616b2 100644
--- a/ui/ozone/platform/wayland/host/wayland_window.cc
+++ b/ui/ozone/platform/wayland/host/wayland_window.cc
@@ -697,8 +697,8 @@
   // event.
   if (AsWaylandPopup())
     return;
-  // Do not update the window scale where. It'll be updated when entring a new
-  // output.
+
+  UpdateWindowScale(true);
 }
 
 WaylandWindow* WaylandWindow::GetTopMostChildWindow() {
diff --git a/ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.cc b/ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.cc
index d585697c..c4f3100 100644
--- a/ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.cc
+++ b/ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.cc
@@ -84,6 +84,10 @@
   static constexpr xdg_toplevel_listener xdg_toplevel_listener = {
       &ConfigureTopLevel,
       &CloseTopLevel,
+      // Since v4
+      &ConfigureBounds,
+      // Since v5
+      &WmCapabilities,
   };
 
   if (!xdg_surface_wrapper_)
@@ -280,6 +284,21 @@
   surface->wayland_window_->OnCloseRequest();
 }
 
+// static
+void XDGToplevelWrapperImpl::ConfigureBounds(void* data,
+                                             struct xdg_toplevel* xdg_toplevel,
+                                             int32_t width,
+                                             int32_t height) {
+  NOTIMPLEMENTED_LOG_ONCE();
+}
+
+// static
+void XDGToplevelWrapperImpl::WmCapabilities(void* data,
+                                            struct xdg_toplevel* xdg_toplevel,
+                                            struct wl_array* capabilities) {
+  NOTIMPLEMENTED_LOG_ONCE();
+}
+
 void XDGToplevelWrapperImpl::SetTopLevelDecorationMode(
     DecorationMode requested_mode) {
   if (!zxdg_toplevel_decoration_ || requested_mode == decoration_mode_)
diff --git a/ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.h b/ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.h
index eebe3482..9e4515bc 100644
--- a/ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.h
+++ b/ui/ozone/platform/wayland/host/xdg_toplevel_wrapper_impl.h
@@ -62,6 +62,13 @@
                                 int32_t height,
                                 struct wl_array* states);
   static void CloseTopLevel(void* data, struct xdg_toplevel* xdg_toplevel);
+  static void ConfigureBounds(void* data,
+                              struct xdg_toplevel* xdg_toplevel,
+                              int32_t width,
+                              int32_t height);
+  static void WmCapabilities(void* data,
+                             struct xdg_toplevel* xdg_toplevel,
+                             struct wl_array* capabilities);
 
   // zxdg_decoration_listener
   static void ConfigureDecoration(
diff --git a/ui/views/animation/ink_drop_mask_unittest.cc b/ui/views/animation/ink_drop_mask_unittest.cc
index f680870..99f69eb8 100644
--- a/ui/views/animation/ink_drop_mask_unittest.cc
+++ b/ui/views/animation/ink_drop_mask_unittest.cc
@@ -37,10 +37,10 @@
   sk_sp<cc::PaintRecord> record = list->ReleaseAsRecord();
   const auto* draw_op = record->GetOpAtForTesting<cc::DrawPathOp>(0);
   ASSERT_NE(nullptr, draw_op);
-  ASSERT_EQ(3, draw_op->path->countPoints());
+  ASSERT_EQ(3, draw_op->path.countPoints());
 
   SkPoint points[3];
-  ASSERT_EQ(3, draw_op->path->getPoints(points, 3));
+  ASSERT_EQ(3, draw_op->path.getPoints(points, 3));
   std::sort(points, points + 3,
             [](const SkPoint& a, const SkPoint& b) { return a.x() < b.x(); });
   EXPECT_EQ(p1, points[0]);
diff --git a/ui/webui/resources/cr_elements/icons.html b/ui/webui/resources/cr_elements/icons.html
index aee974d..f6210575 100644
--- a/ui/webui/resources/cr_elements/icons.html
+++ b/ui/webui/resources/cr_elements/icons.html
@@ -129,6 +129,10 @@
           d="M20 18c1.1 0 1.99-.9 1.99-2L22 6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2H0v2h24v-2h-4zM4 6h16v10H4V6z">
         </path>
       </g>
+      <g id="create">
+        <path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z">
+        </path>
+      </g>
       <g id="delete">
         <path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"></path>
       </g>